From b2e54008ea9332905c5dd30d921c7ee687a04063 Mon Sep 17 00:00:00 2001 From: crouzet Date: Fri, 21 Nov 2003 13:10:02 +0000 Subject: [PATCH 1/1] premiere version --- Makefile.in | 91 ++++++ adm_local/unix/make_commence.in | 249 +++++++++++++++ adm_local/unix/make_omniorb.in | 53 ++++ bin/VERSION | 2 + bin/runAppli.in | 8 + bin/runSalome.py | 506 +++++++++++++++++++++++++++++++ build_configure | 207 +++++++++++++ configure.in.base | 203 +++++++++++++ doc/dev_guide.pdf | Bin 0 -> 118153 bytes doc/dev_guide.txt | 432 ++++++++++++++++++++++++++ idl/Makefile.in | 60 ++++ idl/PYHELLO_Gen.idl | 17 ++ resources/ExecPYHELLO.png | Bin 0 -> 831 bytes resources/PYHELLO.png | Bin 0 -> 831 bytes resources/PYHELLOCatalog.xml | 27 ++ resources/PYHELLO_en.xml | 17 ++ src/Makefile.in | 20 ++ src/PYHELLO/Makefile.in | 20 ++ src/PYHELLO/PYHELLO.py | 25 ++ src/PYHELLOGUI/Makefile.in | 26 ++ src/PYHELLOGUI/PYHELLOGUI.py | 76 +++++ src/PYHELLOGUI/PYHELLO_icons.po | 11 + src/PYHELLOGUI/PYHELLO_msg_en.po | 11 + 23 files changed, 2061 insertions(+) create mode 100644 Makefile.in create mode 100644 adm_local/unix/make_commence.in create mode 100644 adm_local/unix/make_omniorb.in create mode 100755 bin/VERSION create mode 100755 bin/runAppli.in create mode 100755 bin/runSalome.py create mode 100755 build_configure create mode 100644 configure.in.base create mode 100644 doc/dev_guide.pdf create mode 100644 doc/dev_guide.txt create mode 100644 idl/Makefile.in create mode 100644 idl/PYHELLO_Gen.idl create mode 100644 resources/ExecPYHELLO.png create mode 100644 resources/PYHELLO.png create mode 100644 resources/PYHELLOCatalog.xml create mode 100644 resources/PYHELLO_en.xml create mode 100644 src/Makefile.in create mode 100644 src/PYHELLO/Makefile.in create mode 100644 src/PYHELLO/PYHELLO.py create mode 100644 src/PYHELLOGUI/Makefile.in create mode 100644 src/PYHELLOGUI/PYHELLOGUI.py create mode 100644 src/PYHELLOGUI/PYHELLO_icons.po create mode 100644 src/PYHELLOGUI/PYHELLO_msg_en.po diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..a647227 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,91 @@ +# -* Makefile *- +# +# Author : C. Caremoli +# Date : 10/10/2003 +# $Header$ +# + +# source path +top_srcdir=@top_srcdir@ +top_builddir=. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@top_srcdir@/bin:@top_srcdir@/resources:./bin:@top_srcdir@/idl + +@COMMENCE@ + +SUBDIRS = idl src + +RESOURCES_FILES = PYHELLOCatalog.xml PYHELLO.png PYHELLO_en.xml \ + ExecPYHELLO.png + +BIN_SCRIPT= VERSION runAppli runSalome.py + +# copy header files in common directory +ifeq ($(HAVE_SSTREAM),yes) + include_list=include/salome/SALOMEconfig.h +else + include_list=include/salome/SALOMEconfig.h include/salome/sstream +endif + +inc: idl $(include_list) + +include/salome/SALOMEconfig.h: salome_adm/unix/SALOMEconfig.ref + -$(RM) $@ + $(LN_S) ../../$< $@ + +# test if SALOMEconfig.h has changed (contents) +salome_adm/unix/SALOMEconfig.ref: salome_adm/unix/SALOMEconfig.h + @if ! [ -a $@ ]; then \ + cp -p $< $@; \ + fi; \ + if ! cmp $< $@; then \ + cp -p $< $@; \ + fi; \ + +include/salome/sstream: salome_adm/unix/sstream + -$(RM) $@ + $(LN_S) ../../$< $@ + +depend: depend_idl + +depend_idl: + (cd idl ; $(MAKE) $@) || exit 1 + +# doc is already build : if you want to had documents, go manually to doc and run 'make doc' +#doc: +# (cd doc && $(MAKE) $@) || exit 1 + +install-end: +# finish libtool install +# @$(LT) --mode=finish $(libdir) + +install-include: $(include_list) + $(INSTALL) -d $(includedir) + @for f in X $(include_list); do \ + if test $$f != X; then \ + ($(INSTALL_DATA) $$f $(includedir)/. || exit 1); \ + fi; \ + done + +# install script in $(bindir) : +install-bin: $(BIN_SCRIPT) + $(INSTALL) -d $(bindir) + $(INSTALL_PROGRAM) $^ $(bindir) + +uninstall: uninstall-idl + +uninstall-idl: + $(RM) $(idldir)/*.idl + +distclean: distclean-other + +distclean-other: + -$(RM) salome_adm/unix/*~ salome_adm/unix/*% salome_adm/unix/*.bak salome_adm/unix/*.new salome_adm/unix/*.old + -$(RM) salome_adm/unix/make_* + -$(RM) salome_adm/unix/depend salome_adm/unix/SALOMEconfig.h + -$(RM) config.cache config.log config.status + +@MODULE@ + +install: install-bin install-include install-end + diff --git a/adm_local/unix/make_commence.in b/adm_local/unix/make_commence.in new file mode 100644 index 0000000..f6d5ea9 --- /dev/null +++ b/adm_local/unix/make_commence.in @@ -0,0 +1,249 @@ +# common directories to put headerfiles +inc_builddir=$(top_builddir)/include/salome + +@SET_MAKE@ +SHELL=/bin/sh + +# header missing + +HAVE_SSTREAM=@HAVE_SSTREAM@ + + +LIBS=@LIBS@ +LDFLAGS=@LDFLAGS@ -L$(top_builddir)/lib/salome -Xlinker -rpath-link -Xlinker -L$(top_builddir)/lib/salome +# add libstdc++ to link c++ library with libtool ! +LDFLAGS+= -lstdc++ + +CP=@CP@ + +# CPP + +CPP=@CPP@ +CXXCPP=@CXXCPP@ +CPPFLAGS=@CPPFLAGS@ -I$(inc_builddir) -I$(srcdir) -I. + +# C + +CC = @CC@ +CFLAGS = @CFLAGS@ +C_DEPEND_FLAG = @C_DEPEND_FLAG@ + +# C++ + +CXX = @CXX@ +CXXFLAGS = @CXXFLAGS@ +CXX_DEPEND_FLAG = @CXX_DEPEND_FLAG@ + +# JAVA + +JAVA_INCLUDES = @JAVA_INCLUDES@ +JAVA_LIBS = @JAVA_LIBS@ +JAVA_LDPATH = @JAVA_LDPATH@ + +# PYTHON + +PYTHON = @PYTHON@ +PYTHONHOME = @PYTHONHOME@ +PYTHON_INCLUDES = @PYTHON_INCLUDES@ +PYTHON_LIBS = @PYTHON_LIBS@ +PYTHON_VERSION = @PYTHON_VERSION@ +PYTHON_SITE = @PYTHON_SITE@ +PYTHON_SITE_INSTALL = @PYTHON_SITE_INSTALL@ + +# QT + +QT_ROOT = @QT_ROOT@ +QT_INCLUDES = @QT_INCLUDES@ +QT_MT_INCLUDES = @QT_INCLUDES@ -DQT_THREAD_SUPPORT +QT_LIBS = @QT_LIBS@ +QT_MT_LIBS = @QT_MT_LIBS@ + +MOC = @MOC@ +UIC = @UIC@ + + +#QWT + +QWT_INCLUDES=@QWT_INCLUDES@ +QWT_LIBS=@QWT_LIBS@ + +# SIP +SIP = @SIP@ +SIP_INCLUDES = @SIP_INCLUDES@ +SIP_LIBS = @SIP_LIBS@ + +# PYQT +PYQT_SIPS = @PYQT_SIPS@ +PYQT_LIBS = @PYQT_LIBS@ + +# openGL +OGL_INCLUDES=@OGL_INCLUDES@ +OGL_LIBS=@OGL_LIBS@ + +# VTK +VTK_INCLUDES=@VTK_INCLUDES@ +VTK_LIBS=@VTK_LIBS@ + +# HDF5 + +HDF5_INCLUDES=@HDF5_INCLUDES@ +HDF5_LIBS=@HDF5_LIBS@ +HDF5_MT_LIBS=@HDF5_MT_LIBS@ + +# MED2 + +MED2_INCLUDES=@MED2_INCLUDES@ +MED2_LIBS=@MED2_LIBS@ +MED2_MT_LIBS=@MED2_MT_LIBS@ + +# OpenCasCade + +OCC_INCLUDES=@CAS_CPPFLAGS@ +OCC_CXXFLAGS=@CAS_CXXFLAGS@ + +OCC_KERNEL_LIBS=@CAS_KERNEL@ +OCC_OCAF_LIBS=@CAS_OCAF@ +OCC_VIEWER_LIBS=@CAS_VIEWER@ +OCC_MODELER_LIBS=@CAS_MODELER@ +OCC_DATAEXCHANGE_LIBS=@CAS_DATAEXCHANGE@ +OCC_LIBS=@CAS_LDFLAGS@ + +# MPICH + +MPICH_INCLUDES=@MPICH_INCLUDES@ +MPICH_LIBS=@MPICH_LIBS@ + +# Swig C++ Python + +SWIG = @SWIG@ +SWIG_FLAGS = @SWIG_FLAGS@ -I$(inc_builddir) -I$(srcdir) -I. + +# OMNIORB + +OMNIORB_ROOT = @OMNIORB_ROOT@ +OMNIORB_INCLUDES = @OMNIORB_INCLUDES@ +OMNIORB_LIBS = @OMNIORB_LIBS@ +OMNIORB_CXXFLAGS = @OMNIORB_CXXFLAGS@ + +OMNIORB_IDL = @OMNIORB_IDL@ +OMNIORB_IDLCXXFLAGS = @OMNIORB_IDLCXXFLAGS@ +OMNIORB_IDLPYFLAGS = @OMNIORB_IDLPYFLAGS@ -I$(top_srcdir)/idl -I$(top_builddir)/idl -I$(KERNEL_ROOT_DIR)/idl/salome + +OMNIORB_IDL_CLN_H = @OMNIORB_IDL_CLN_H@ +OMNIORB_IDL_CLN_CXX = @OMNIORB_IDL_CLN_CXX@ +OMNIORB_IDL_CLN_OBJ = @OMNIORB_IDL_CLN_OBJ@ + +OMNIORB_IDL_SRV_H = @OMNIORB_IDL_SRV_H@ +OMNIORB_IDL_SRV_CXX = @OMNIORB_IDL_SRV_CXX@ +OMNIORB_IDL_SRV_OBJ = @OMNIORB_IDL_SRV_OBJ@ + +# Default ORB + +CORBA_ROOT = @CORBA_ROOT@ +CORBA_INCLUDES = @CORBA_INCLUDES@ +CORBA_LIBS = @CORBA_LIBS@ +CORBA_CXXFLAGS = @CORBA_CXXFLAGS@ + +IDLCXXFLAGS = -bcxx @IDLCXXFLAGS@ -I$(top_srcdir)/idl -I$(top_builddir)/idl -I$(KERNEL_ROOT_DIR)/idl/salome +IDLPYFLAGS = @IDLPYFLAGS@ + +IDL = @IDL@ + +IDL_CLN_H = @IDL_CLN_H@ +IDL_CLN_CXX = @IDL_CLN_CXX@ +IDL_CLN_OBJ = @IDL_CLN_OBJ@ + +IDL_SRV_H = @IDL_SRV_H@ +IDL_SRV_CXX = @IDL_SRV_CXX@ +IDL_SRV_OBJ = @IDL_SRV_OBJ@ + +CPPFLAGS+= $(CORBA_INCLUDES) +CXXFLAGS+= $(CORBA_CXXFLAGS) + +# add corba libs when link salome application ! +#LDFLAGS+= $(CORBA_LIBS) +LIBS+=$(CORBA_LIBS) + +## Shared libraries +LT_STATIC_EXEC=@LT_STATIC_EXEC@ +DYNAMIC_DIRS=@DYNAMIC_DIRS@ +LT_LIB=libtool +LT=$(top_builddir)/libtool +LT_COMPILE=$(LT) --mode=compile $(CC) +LT_LINK_LIB=$(LT_LIB) --mode=link $(CC) -rpath $(libdir) +LT_LINK_EXE=$(LT) --mode=link $(CC) $(LT_STATIC_EXEC) -dlopen self -rpath $(bindir) $(DYNAMIC_DIRS) +LT_RUN=$(LT) --mode=execute +LT_INSTALL_PROG=$(LT) --mode=install $(INSTALL_PROGRAM) +LT_INSTALL_LIB=$(LT) --mode=install $(INSTALL_DATA) +LT_UNINSTALL=$(LT) --mode=uninstall $(RM) + +INSTALL=@INSTALL@ +INSTALL_PROGRAM=@INSTALL_PROGRAM@ +INSTALL_DATA=@INSTALL_DATA@ + +# create a symbolic link (or a copie ?) +LN_S=@LN_S@ + +## Installation points +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@/salome +libdir=@libdir@/salome +# warning : if user give this path in configure we could have salome/salome :-( +includedir=@includedir@/salome +datadir=@datadir@/salome +idldir=$(prefix)/idl/salome +sharedpydir=@libdir@/python$(PYTHON_VERSION)/site-packages/salome/shared_modules + +docdir=$(datadir)/doc + +# +# begin of package rules +# + +.PHONY: all lib bin inc resources tests install uninstall dep depend depend_idl cleandep mostlyclean clean distclean + +.SUFFIXES: .cxx .cc .c .f .o .lo .idl .py .i .ui .po .qm + +all: + $(MAKE) inc + $(MAKE) depend_idl + $(MAKE) depend + $(MAKE) lib + $(MAKE) bin + $(MAKE) resources + +# +# add target to build administrative files +# + +Makefile: $(top_builddir)/config.status $(srcdir)/Makefile.in + cd $(top_builddir) ; ./config.status + +$(top_builddir)/config.status: $(top_srcdir)/configure + cd $(top_builddir) ; ./config.status --recheck + +# VPATH contain $(srcdir), so make configure is good in top_srcdir and we must add target configure otherwise :-) +ifneq ($(top_srcdir),$(srcdir)) +configure: $(top_srcdir)/configure +endif + +$(top_srcdir)/configure: $(top_srcdir)/configure.in $(top_srcdir)/aclocal.m4 + cd $(top_srcdir) ; autoconf + +$(top_srcdir)/configure.in: $(top_srcdir)/configure.in.base + cd $(top_srcdir) && ./build_configure + + +ACLOCAL_SRC = \ +ac_cxx_bool.m4 check_corba.m4 check_vtk.m4 \ +ac_cxx_depend_flag.m4 check_hdf5.m4 enable_pthreads.m4 \ +ac_cxx_mutable.m4 check_mico.m4 libtool.m4 \ +ac_cxx_namespaces.m4 check_omniorb.m4 pyembed.m4 \ +ac_cxx_partial_specialization.m4 check_opengl.m4 python.m4 \ +ac_cxx_typename.m4 check_pthreads.m4 check_cas.m4 \ +ac_cc_warnings.m4 check_qt.m4 check_med2.m4 \ +check_swig.m4 + +$(top_srcdir)/aclocal.m4: $(ACLOCAL_SRC:%=@KERNEL_ROOT_DIR@/salome_adm/unix/config_files/%) + cd $(top_srcdir) ; aclocal --acdir=adm_local/unix/config_files -I @KERNEL_ROOT_DIR@/salome_adm/unix/config_files diff --git a/adm_local/unix/make_omniorb.in b/adm_local/unix/make_omniorb.in new file mode 100644 index 0000000..84679a9 --- /dev/null +++ b/adm_local/unix/make_omniorb.in @@ -0,0 +1,53 @@ +#======================================================================= +# Begin specific part to omniorb +# (include from file adm/unix/make_omniorb generated by +# adm/unix/make_omniorb.in) +#======================================================================= +# -* Makefile *- +# +# Author : Patrick GOLDBRONN (CEA) +# Date : 29/06/2001 +# $Header$ +# + +# Client and server object are the same with omniorb +# There are one header file and one source file generate + +#IDLOBJ=$(IDLSRC:%.idl=%$(IDL_CLN_OBJ)) + +# dependancies between idl and it's generated files +%$(OMNIORB_IDL_CLN_CXX) %$(OMNIORB_IDL_CLN_H): ${KERNEL_ROOT_DIR}/idl/salome/%.idl + $(OMNIORB_IDL) $(IDLCXXFLAGS) $(OMNIORB_IDLCXXFLAGS) $< + +%$(OMNIORB_IDL_CLN_CXX) %$(OMNIORB_IDL_CLN_H): ${top_srcdir}/idl/%.idl + $(OMNIORB_IDL) $(IDLCXXFLAGS) $(OMNIORB_IDLCXXFLAGS) $< + +# dependncies between idl files +depend_idl: .depidl + +# we use cpp to generate dependencies between idl files. +# we change cpp output to keep only idl file and transform it to get a suitable rule +.depidl: $(IDL_FILES) + @touch $@ + @for dep in $? dummy; do \ + if [ $$dep != "dummy" ]; then \ + echo Building dependencies for $$dep; \ + basedep=`basename $$dep .idl`; \ + header="$$basedep"$(IDL_CLN_H); \ + sed '\%^'"$$header"':%,\%[^\\]$$%d' <$@ >$@- && mv $@- $@; \ + $(CPP) $(C_DEPEND_FLAG) -I$(srcdir) $$dep 2>/dev/null | \ + sed `echo "s%$$basedep\\.idl%$$header:%g"` | \ + sed 's% $(srcdir)/% %g' | \ + sed 's% $(top_srcdir)/% %g' | \ + sed 's% $(top_builddir)/% %g' | \ + sed 's%^.*:\.o: *%%' | sed 's%^ *\\ *%%'| sed 's%^ *\(.*\):%\1:%' | \ + sed 's/\.idl/$(IDL_CLN_H)/' >>$@; \ + echo '' >>$@; \ + fi; \ + done ; + +-include .depidl + +#======================================================================= +# End specific part to omniorb +#======================================================================= diff --git a/bin/VERSION b/bin/VERSION new file mode 100755 index 0000000..1899fd1 --- /dev/null +++ b/bin/VERSION @@ -0,0 +1,2 @@ +SALOME 2 EXAMPLE MODULE : PYHELLO +This module works with KERNEL 1.2.1 diff --git a/bin/runAppli.in b/bin/runAppli.in new file mode 100755 index 0000000..9a47b00 --- /dev/null +++ b/bin/runAppli.in @@ -0,0 +1,8 @@ +#!/bin/sh + +export KERNEL_ROOT_DIR=@KERNEL_ROOT_DIR@ +export PYHELLO_ROOT_DIR=@prefix@ + +python -i $PYHELLO_ROOT_DIR/bin/salome/runSalome.py --modules=PYHELLO --xterm --containers=cpp,python --killall + + diff --git a/bin/runSalome.py b/bin/runSalome.py new file mode 100755 index 0000000..c7eb2e7 --- /dev/null +++ b/bin/runSalome.py @@ -0,0 +1,506 @@ +#!/usr/bin/env python + +usage="""USAGE: runSalome.py [options] + +[command line options] : +--help : affichage de l'aide +--gui : lancement du GUI +--logger : redirection des messages dans un fichier +--xterm : les serveurs ouvrent une fenêtre xterm et les messages sont affichés dans cette fenêtre +--modules=module1,module2,... : où modulen est le nom d'un module Salome à charger dans le catalogue +--containers=cpp,python,superv: lancement des containers cpp, python et de supervision +--killall : arrêt des serveurs de salome + + La variable d'environnement _ROOT_DIR doit etre préalablement + positionnée (modulen doit etre en majuscule). + KERNEL_ROOT_DIR est obligatoire. +""" + +# ----------------------------------------------------------------------------- +# +# Fonction d'arrêt de salome +# + +def killSalome(): + print "arret des serveurs SALOME" + for pid, cmd in process_id.items(): + print "arret du process %s : %s"% (pid, cmd[0]) + try: + os.kill(pid,signal.SIGKILL) + except: + print " ------------------ process %s : %s inexistant"% (pid, cmd[0]) + print "arret du naming service" + os.system("killall -9 omniNames") + +# ----------------------------------------------------------------------------- +# +# Fonction message +# + +def message(code, msg=''): + if msg: print msg + sys.exit(code) + +import sys,os,string,glob,time,signal,pickle,getopt + +init_time=os.times() +opts, args=getopt.getopt(sys.argv[1:], 'hmglxck:', ['help','modules=','gui','logger','xterm','containers=','killall']) +modules_root_dir={} +process_id={} +liste_modules={} +liste_containers={} +with_gui=0 +with_logger=0 +with_xterm=0 + +with_container_cpp=0 +with_container_python=0 +with_container_superv=0 + +try: + for o, a in opts: + if o in ('-h', '--help'): + print usage + sys.exit(1) + elif o in ('-g', '--gui'): + with_gui=1 + elif o in ('-l', '--logger'): + with_logger=1 + elif o in ('-x', '--xterm'): + with_xterm=1 + elif o in ('-m', '--modules'): + liste_modules = [x.upper() for x in a.split(',')] + elif o in ('-c', '--containers'): + liste_containers = [x.lower() for x in a.split(',')] + for r in liste_containers: + if r not in ('cpp', 'python', 'superv'): + message(1, 'Invalid -c/--containers option: %s' % a) + if 'cpp' in liste_containers: + with_container_cpp=1 + else: + with_container_cpp=0 + if 'python' in liste_containers: + with_container_python=1 + else: + with_container_python=0 + if 'superv' in liste_containers: + with_container_superv=1 + else: + with_container_superv=0 + elif o in ('-k', '--killall'): + filedict='/tmp/'+os.getenv('USER')+'_SALOME_pidict' + #filedict='/tmp/'+os.getlogin()+'_SALOME_pidict' + found = 0 + try: + fpid=open(filedict, 'r') + found = 1 + except: + print "le fichier %s des process SALOME n'est pas accessible"% filedict + + if found: + process_id=pickle.load(fpid) + fpid.close() + killSalome() + process_id={} + os.remove(filedict) + +except getopt.error, msg: + print usage + sys.exit(1) + +# ----------------------------------------------------------------------------- +# +# Vérification des variables d'environnement +# +try: + kernel_root_dir=os.environ["KERNEL_ROOT_DIR"] + modules_root_dir["KERNEL"]=kernel_root_dir +except: + print usage + sys.exit(1) + +for module in liste_modules : + try: + module=module.upper() + module_root_dir=os.environ[module +"_ROOT_DIR"] + modules_root_dir[module]=module_root_dir + except: + print usage + sys.exit(1) + +# il faut KERNEL en premier dans la liste des modules +# - l'ordre des modules dans le catalogue sera identique +# - la liste des modules presents dans le catalogue est exploitée pour charger les modules CORBA python, +# il faut charger les modules python du KERNEL en premier + +if "KERNEL" in liste_modules:liste_modules.remove("KERNEL") +liste_modules[:0]=["KERNEL"] +#print liste_modules +#print modules_root_dir + +os.environ["SALOMEPATH"]=":".join(modules_root_dir.values()) +if "SUPERV" in liste_modules:with_container_superv=1 + + +# ----------------------------------------------------------------------------- +# +# Définition des classes d'objets pour le lancement des Server CORBA +# + +class Server: + CMD=[] + if with_xterm: + ARGS=['xterm', '-iconic', '-sb', '-sl', '500', '-e'] + else: + ARGS=[] + + def run(self): + args = self.ARGS+self.CMD + #print "args = ", args + pid = os.spawnvp(os.P_NOWAIT, args[0], args) + process_id[pid]=self.CMD + +class CatalogServer(Server): + SCMD1=['SALOME_ModuleCatalog_Server','-common'] + SCMD2=['-personal','${HOME}/Salome/resources/CatalogModulePersonnel.xml'] + + def setpath(self,liste_modules): + cata_path=[] + for module in liste_modules: + module_root_dir=modules_root_dir[module] + module_cata=module+"Catalog.xml" + print " ", module_cata + cata_path.extend(glob.glob(os.path.join(module_root_dir,"share","salome","resources",module_cata))) + self.CMD=self.SCMD1 + [string.join(cata_path,':')] + self.SCMD2 + +class SalomeDSServer(Server): + CMD=['SALOMEDS_Server'] + +class RegistryServer(Server): + CMD=['SALOME_Registry_Server', '--salome_session','theSession'] + +class ContainerCPPServer(Server): + CMD=['SALOME_Container','FactoryServer','-ORBInitRef','NameService=corbaname::localhost'] + +class ContainerPYServer(Server): + CMD=['SALOME_ContainerPy.py','FactoryServerPy','-ORBInitRef','NameService=corbaname::localhost'] + +class ContainerSUPERVServer(Server): + CMD=['SALOME_Container','SuperVisionContainer','-ORBInitRef','NameService=corbaname::localhost'] + +class LoggerServer(Server): + CMD=['SALOME_Logger_Server', 'logger.log'] + +class SessionLoader(Server): + CMD=['SALOME_Session_Loader'] + if with_container_cpp: + CMD=CMD+['CPP'] + if with_container_python: + CMD=CMD+['PY'] + if with_container_superv: + CMD=CMD+['SUPERV'] + if with_gui: + CMD=CMD+['GUI'] + +class SessionServer(Server): + CMD=['SALOME_Session_Server'] + +class NotifyServer(Server): + CMD=['notifd','-c','${KERNEL_ROOT_DIR}/share/salome/resources/channel.cfg -DFactoryIORFileName=/tmp/${LOGNAME}_rdifact.ior -DChannelIORFileName=/tmp/${LOGNAME}_rdichan.ior'] + +# ----------------------------------------------------------------------------- +# +# Fonction de test +# + +def test(clt): + """ + Test function that creates an instance of PYHELLO component + usage : pyhello=test(clt) + """ + # create an LifeCycleCORBA instance + import LifeCycleCORBA + lcc = LifeCycleCORBA.LifeCycleCORBA(clt.orb) + import PYHELLO_ORB + pyhello = lcc.FindOrLoadComponent("FactoryServerPy", "PYHELLO") + return pyhello + +# ----------------------------------------------------------------------------- +# +# Fonctions helper pour ajouter des variables d'environnement +# + +def add_path(directory): + os.environ["PATH"]=directory + ":" + os.environ["PATH"] + +def add_ld_library_path(directory): + os.environ["LD_LIBRARY_PATH"]=directory + ":" + os.environ["LD_LIBRARY_PATH"] + +def add_python_path(directory): + os.environ["PYTHONPATH"]=directory + ":" + os.environ["PYTHONPATH"] + sys.path[:0]=[directory] + +# ----------------------------------------------------------------------------- +# +# initialisation des variables d'environnement +# + +python_version="python%d.%d" % sys.version_info[0:2] + +# +# Ajout du chemin d'acces aux executables de KERNEL dans le PATH +# + +add_path(os.path.join(kernel_root_dir,"bin","salome")) +#print "PATH=",os.environ["PATH"] + +# +# Ajout des modules dans le LD_LIBRARY_PATH +# +for module in liste_modules: + module_root_dir=modules_root_dir[module] + add_ld_library_path(os.path.join(module_root_dir,"lib","salome")) +#print "LD_LIBRARY_PATH=",os.environ["LD_LIBRARY_PATH"] + +# +# Ajout des modules dans le PYTHONPATH (KERNEL prioritaire, donc en dernier) +# + +liste_modules_reverse=liste_modules[:] +liste_modules_reverse.reverse() +#print liste_modules +#print liste_modules_reverse +for module in liste_modules_reverse: + module_root_dir=modules_root_dir[module] + add_python_path(os.path.join(module_root_dir,"bin","salome")) + add_python_path(os.path.join(module_root_dir,"lib",python_version,"site-packages","salome")) + add_python_path(os.path.join(module_root_dir,"lib","salome")) + add_python_path(os.path.join(module_root_dir,"lib",python_version,"site-packages","salome","shared_modules")) + +#print "PYTHONPATH=",sys.path + +import orbmodule + +# +# ----------------------------------------------------------------------------- +# + +def startGUI(): + import SALOME + session=clt.waitNS("/Kernel/Session",SALOME.Session) + + # + # Activation du GUI de Session Server + # + + session.GetInterface() + +# +# ----------------------------------------------------------------------------- +# + +def startSalome(): + + # + # Lancement Session Loader + # + SessionLoader().run() + + # + # Initialisation ORB et Naming Service + # + clt=orbmodule.client() + + # (non obligatoire) Lancement Logger Server et attente de sa + # disponibilite dans le naming service + # + if with_logger: + LoggerServer().run() + clt.waitLogger("Logger") + + # + # Lancement Registry Server + # + RegistryServer().run() + + # + # Attente de la disponibilité du Registry dans le Naming Service + # + clt.waitNS("/Registry") + + # + # Lancement Catalog Server + # + cataServer=CatalogServer() + cataServer.setpath(liste_modules) + cataServer.run() + + # + # Attente de la disponibilité du Catalog Server dans le Naming Service + # + import SALOME_ModuleCatalog + clt.waitNS("/Kernel/ModulCatalog",SALOME_ModuleCatalog.ModuleCatalog) + + # + # Lancement SalomeDS Server + # + os.environ["CSF_PluginDefaults"]=os.path.join(kernel_root_dir,"share","salome","resources") + os.environ["CSF_SALOMEDS_ResourcesDefaults"]=os.path.join(kernel_root_dir,"share","salome","resources") + SalomeDSServer().run() + + if "GEOM" in liste_modules: + print "GEOM OCAF Resources" + os.environ["CSF_GEOMDS_ResourcesDefaults"]=os.path.join(modules_root_dir["GEOM"],"share","salome","resources") + + + # + # Attente de la disponibilité du SalomeDS dans le Naming Service + # + clt.waitNS("/myStudyManager") + + # + # Lancement Session Server + # + SessionServer().run() + + # + # Attente de la disponibilité du Session Server dans le Naming Service + # + import SALOME + session=clt.waitNS("/Kernel/Session",SALOME.Session) + + # + # Lancement containers + # + theComputer = os.getenv("HOSTNAME") + theComputer = theComputer.split('.')[0] + + # + # Lancement Container C++ local + # + if with_container_cpp: + ContainerCPPServer().run() + # + # Attente de la disponibilité du Container C++ local + # dans le Naming Service + # + clt.waitNS("/Containers/" + theComputer + "/FactoryServer") + # + # Lancement Container Python local + # + if with_container_python: + ContainerPYServer().run() + # + # Attente de la disponibilité du Container Python local + # dans le Naming Service + # + clt.waitNS("/Containers/" + theComputer + "/FactoryServerPy") + + if with_container_superv: + # + # Lancement Container Supervision local + # + ContainerSUPERVServer().run() + # + # Attente de la disponibilité du Container Supervision local + # dans le Naming Service + # + clt.waitNS("/Containers/" + theComputer + "/SuperVisionContainer") + # + # Activation du GUI de Session Server + # + #session.GetInterface() + + end_time = os.times() + print + print "Start SALOME, elpased time : %5.1f seconds"% (end_time[4] - init_time[4]) + + return clt + +# +# ----------------------------------------------------------------------------- +# + +if __name__ == "__main__": + clt=None + try: + clt = startSalome() + except: + print + print + print "--- erreur au lancement Salome ---" + + #print process_id + + + filedict='/tmp/'+os.getenv('USER')+'_SALOME_pidict' + #filedict='/tmp/'+os.getlogin()+'_SALOME_pidict' + + fpid=open(filedict, 'w') + pickle.dump(process_id,fpid) + fpid.close() + + print """ + +Sauvegarde du dictionnaire des process dans , %s +Pour tuer les process SALOME, executer : python killSalome.py depuis +une console, ou bien killSalome() depuis le present interpreteur, +s'il n'est pas fermé. + +runSalome, avec l'option --killall, commence par tuer les process restants +d'une execution précédente. + +Pour lancer uniquement le GUI, executer startGUI() depuis le present interpreteur, +s'il n'est pas fermé. + +""" % filedict + + # + # Impression arborescence Naming Service + # + + if clt != None: + print + print " --- registered objects tree in Naming Service ---" + clt.showNS() + session=clt.waitNS("/Kernel/Session") + catalog=clt.waitNS("/Kernel/ModulCatalog") + import socket + container = clt.waitNS("/Containers/" + socket.gethostname().split('.')[0] + "/FactoryServerPy") + + if os.path.isfile("~/.salome/pystartup"): + f=open(os.path.expanduser("~/.salome/pystartup"),'w') + PYTHONSTARTUP=f.read() + f.close() + else: + PYTHONSTARTUP=""" +# Add auto-completion and a stored history file of commands to your Python +# interactive interpreter. Requires Python 2.0+, readline. Autocomplete is +# bound to the TAB key by default (you can change it - see readline docs). +# +# Store the history in ~/.salome/pyhistory, +# +import atexit +import os +import readline +import rlcompleter +readline.parse_and_bind('tab: complete') + +historyPath = os.path.expanduser("~/.salome/pyhistory") + +def save_history(historyPath=historyPath): + import readline + readline.write_history_file(historyPath) + +if os.path.exists(historyPath): + readline.read_history_file(historyPath) + +atexit.register(save_history) +del os, atexit, readline, rlcompleter, save_history, historyPath +""" + f=open(os.path.expanduser("~/.salome/pystartup"),'w') + f.write(PYTHONSTARTUP) + f.close() + + exec PYTHONSTARTUP in {} + diff --git a/build_configure b/build_configure new file mode 100755 index 0000000..573a23b --- /dev/null +++ b/build_configure @@ -0,0 +1,207 @@ +#!/bin/bash + +# +# Tool for updating list of .in file for the SALOME project +# and regenerating configure script +# +# Author : Marc Tajchman - CEA +# Date : 10/10/2002 +# $Header $ +# + +ORIG_DIR=`pwd` +CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"` + +######################################################################## +# Test if the KERNEL_ROOT_DIR is set correctly + +if test ! -d "${KERNEL_ROOT_DIR}"; then + echo "failed : KERNEL_ROOT_DIR variable is not correct !" + exit +fi + +######################################################################## +# find_in - utility function +# +# usage : +# find_in directory filename +# +# Finds files following the *.in pattern, recursively in the +# directory (first argument). +# Results are appended into the file (second argument) +# +# Difference from the standard unix find is that files are tested +# before directories +# + +find_in() +{ + local i + local f=$2 + +# if the first argument is not a directory, returns + + if [ ! -d "$1" ] ; then + return + fi + +# dont look in the CVS directories + + case $1 in + */CVS) return ;; + *) ;; + esac + +# for each regular file contained in the directory +# test if it's a .in file + + for i in "$1"/* + do + if [ -f "$i" ] ; then + case $i in + *.in) echo $i" \\" >> $f;; + *) ;; + esac + fi + done + +# for each subdirectory of the first argument, proceeds recursively + + for i in "$1"/* + do + if [ -d "$i" ] ; then + find_in "$i" "$f" + fi + done +} + + +####################################################################### +# Generate list of .in files (Makefile.in, config.h.in, etc) +# appending it in file configure.in + +cd ${CONF_DIR} +ABS_CONF_DIR=`pwd` + +# +# Common part of the configure.in file +# +chmod u+w configure.in.base +if ! \cp -f configure.in.base configure.in_tmp1 +then + echo + echo "error : can't create files in" ${CONF_DIR} + echo "aborting ..." + chmod u-w configure.in.base + exit +fi +chmod u-w configure.in.base + +if [ -e "${CONF_DIR}/salome_adm" ] ; then + \rm -f ${CONF_DIR}/salome_adm +fi + +# make a link allowing AC_OUTPUT to find the salome_adm/.../*.in files +echo "" >> configure.in_tmp1 +echo 'ln -fs ${KERNEL_ROOT_DIR}/salome_adm ${ROOT_SRCDIR}' >> configure.in_tmp1 + +echo "" >> configure.in_tmp1 +echo "AC_OUTPUT([ \\" >> configure.in_tmp1 + +# +# List of .in files in the adm/unix directory +# These files MUST be on top of AC_OUTPUT list so we +# put them "manually" +# + +echo "./salome_adm/unix/SALOMEconfig.h \\" >> configure.in_tmp1 +echo "./salome_adm/unix/F77config.h \\" >> configure.in_tmp1 +echo "./salome_adm/unix/sstream \\" >> configure.in_tmp1 +echo "./salome_adm/unix/depend \\" >> configure.in_tmp1 +echo "./adm_local/unix/make_omniorb \\" >> configure.in_tmp1 +echo "./salome_adm/unix/envScript \\" >> configure.in_tmp1 +echo "./adm_local/unix/make_commence \\" >> configure.in_tmp1 +echo "./salome_adm/unix/make_conclude \\" >> configure.in_tmp1 +echo "./salome_adm/unix/make_module \\" >> configure.in_tmp1 + +\rm -f configure.in_tmp2 +touch configure.in_tmp2 +find_in . configure.in_tmp2 + +sed -e '/^.\/salome_adm/d' \ + -e '/configure.in/d' \ + -e '/^.\/adm_local/d' \ + -e 's/.in / /' \ + configure.in_tmp2 >> configure.in_tmp1 + +echo "])" >> configure.in_tmp1 + +# delete the link created for AC_OUTPUT +echo "" >> configure.in_tmp1 +\mv configure.in_tmp1 configure.in_new +\rm -f configure.in_tmp2 + + +######################################################################## +# Create new (or replace old) configure.in file +# Print a message if the file is write protected +# + +echo +if test ! -f configure.in +then + echo -n "Creating new file 'configure.in' ... " + if \mv configure.in_new configure.in >& /dev/null + then + echo "done" + else + echo "error, check your file permissions" + fi +else + echo -n "Updating 'configure.in' file ... " + if ! \cp configure.in configure.in_old >& /dev/null + then + echo + echo + echo "Can't backup previous configure.in" + echo -n "Continue (you will not be able to revert) - (Y/N) ? " + read R + case "x$R" in + xn*) exit;; + xN*) exit;; + esac + echo + echo -n " " + fi + if \cp configure.in_new configure.in >& /dev/null + then + \rm -f configure.in_new + echo "done" + else + echo + echo "error, can't update previous configure.in" + fi +fi + +######################################################################## +# Use autoconf to rebuild the configure script +# + +if test -f configure +then + echo -n "Updating 'configure' script ... " +else + echo -n "Creating 'configure' script ... " +fi + +aclocal --acdir=adm_local/unix/config_files -I ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files +if autoconf +then + echo "done" +else + echo "failed (check file permissions and/or user quotas ...)" +fi + +cd ${ORIG_DIR} + +echo diff --git a/configure.in.base b/configure.in.base new file mode 100644 index 0000000..151b274 --- /dev/null +++ b/configure.in.base @@ -0,0 +1,203 @@ +# +# PLEASE DO NOT MODIFY configure.in FILE +# +# ALL CHANGES WILL BE DISCARDED BY THE NEXT +# build_configure COMMAND +# +# CHANGES MUST BE MADE IN configure.in.base FILE +# +# +# Author : Marc Tajchman (CEA) +# Date : 28/06/2001 +# Modified by : Patrick GOLDBRONN (CEA) +# Modified by : Marc Tajchman (CEA) +# +# Created from configure.in.base +# + +AC_INIT(src) +AC_CONFIG_AUX_DIR(${KERNEL_ROOT_DIR}/salome_adm/unix/config_files) +AC_CANONICAL_HOST + +PACKAGE=salome +AC_SUBST(PACKAGE) + +VERSION=1.2.1 +AC_SUBST(VERSION) + +dnl +dnl Initialize source and build root directories +dnl + +ROOT_BUILDDIR=`pwd` +ROOT_SRCDIR=`echo $0 | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` +cd $ROOT_SRCDIR +ROOT_SRCDIR=`pwd` +cd $ROOT_BUILDDIR + +AC_SUBST(ROOT_SRCDIR) +AC_SUBST(ROOT_BUILDDIR) + +echo +echo Source root directory : $ROOT_SRCDIR +echo Build root directory : $ROOT_BUILDDIR +echo +echo + +if test -z "$AR"; then + AC_CHECK_PROGS(AR,ar xar,:,$PATH) +fi +AC_SUBST(AR) + +dnl Export the AR macro so that it will be placed in the libtool file +dnl correctly. +export AR + +echo +echo --------------------------------------------- +echo testing make +echo --------------------------------------------- +echo + +AC_PROG_MAKE_SET +AC_PROG_INSTALL +dnl +dnl libtool macro check for CC, LD, NM, LN_S, RANLIB, STRIP + for shared libraries + +AC_ENABLE_DEBUG(yes) +AC_DISABLE_PRODUCTION + +echo --------------------------------------------- +echo testing libtool +echo --------------------------------------------- + +dnl first, we set static to no! +dnl if we want it, use --enable-static +AC_ENABLE_STATIC(no) + +AC_LIBTOOL_DLOPEN +AC_PROG_LIBTOOL + +dnl Fix up the INSTALL macro if it s a relative path. We want the +dnl full-path to the binary instead. +case "$INSTALL" in + *install-sh*) + INSTALL='\${KERNEL_ROOT_DIR}'/salome_adm/unix/config_files/install-sh + ;; +esac + +echo +echo --------------------------------------------- +echo testing python +echo --------------------------------------------- +echo + +CHECK_PYTHON + +echo +echo --------------------------------------------- +echo testing omniORB +echo --------------------------------------------- +echo + +CHECK_OMNIORB + +echo +echo --------------------------------------------- +echo default ORB : omniORB +echo --------------------------------------------- +echo + +DEFAULT_ORB=omniORB +CHECK_CORBA + +AC_SUBST_FILE(CORBA) +corba=make_$ORB +CORBA=adm_local/unix/$corba + +echo +echo --------------------------------------------- +echo Testing Kernel +echo --------------------------------------------- +echo + +CHECK_KERNEL + +echo +echo --------------------------------------------- +echo Summary +echo --------------------------------------------- +echo + +echo Configure +variables="python_ok omniORB_ok Kernel_ok" + +for var in $variables +do + printf " %10s : " `echo \$var | sed -e "s,_ok,,"` + eval echo \$$var +done + +echo +echo "Default ORB : $DEFAULT_ORB" +echo + +dnl generals files which could be included in every makefile + +AC_SUBST_FILE(COMMENCE) COMMENCE=adm_local/unix/make_commence +AC_SUBST_FILE(CONCLUDE) CONCLUDE=salome_adm/unix/make_conclude +AC_SUBST_FILE(MODULE) MODULE=salome_adm/unix/make_module + +dnl les dependences +AC_SUBST_FILE(DEPEND) DEPEND=salome_adm/unix/depend + +dnl We don t need to say when we re entering directories if we re using +dnl GNU make becuase make does it for us. +if test "X$GMAKE" = "Xyes"; then + AC_SUBST(SETX) SETX=":" +else + AC_SUBST(SETX) SETX="set -x" +fi + +# make other build directories +for rep in salome_adm adm_local doc bin/salome include/salome lib/salome share/salome/resources share/salome/doc idl +do + $INSTALL -d $rep +done + +echo +echo --------------------------------------------- +echo copying resource files, shell scripts, and +echo xml files +echo --------------------------------------------- +echo + +dnl copy shells and utilities contained in the bin directory +dnl excluding .in files (treated in AC-OUTPUT below) and CVS +dnl directory + +cd bin +for i in $ROOT_SRCDIR/bin/* +do + local_bin=`echo $i | sed -e "s,$ROOT_SRCDIR,.,"` + case "$local_bin" in + *.in | *~) ;; + ./bin/CVS) ;; + *) ln -fs $i; echo $local_bin ;; + esac +done +cd $ROOT_BUILDDIR + +AC_SUBST_FILE(ENVSCRIPT) ENVSCRIPT=salome_adm/unix/envScript + +echo +echo --------------------------------------------- +echo generating Makefiles and configure files +echo --------------------------------------------- +echo + +AC_OUTPUT_COMMANDS([ \ + chmod +x ./bin/* \ +]) + +## do not delete this line diff --git a/doc/dev_guide.pdf b/doc/dev_guide.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1d500f67dd963c4688e29e40d72b8e78d28f3a18 GIT binary patch literal 118153 zcmb?D2RxPS+afcij8MjjtZL{YL+85JTD z5qDL{gFl>tIf}3$uPVzwG+Y0>oe7u)jd$h!=JSh)i6paSlHt zgCmI8;1GQn3Im$+d?|1*ejrt4RcoRoQtevy4vnyWM4(lvzk27~Ad}3XM&2aXP zIA;^E0%2zpJDfdM7_o^uapnAoHR_sc$RGe21R#N|BZFXFAU}{nw4_y!tI0zUKbRxR zWU~YbjJTLMf`84ifE@>C7rd((K?=g=uIro%V?D6;j&|6eIYSUd$&Xy)OciiLkjyGJ zh&dMU^8*{i+;yE*$U3&~tRaX3-praAUU+ps2%Omoo8V1xc&xJ-*1-(>gSSmQ5x0OJ zwZ@a|>Rzp4A#h~Jw-L(^o__E`6!&Ic?5&-#!dM4k9M;th59kYw z#bcrHjXH=R3Y;GWT~{16fCGYcfUMzwnDY^F2oXfJhU7aZNTPT*bAlIk#Nu6W)_@CZ zbGx63B8j2|M2Y%B*b*WH1VH?tKor*BP;kbZZK6OF5TLNW@0veR01!VY5M}T;6dXOR zuy%GhC}N}Vz$sfh?*uAD@%>CkT~|q7RrUCHS}5Yu|Av-1ZqsT|L=gZw>l*Vj6#(&r z0&(eoL&4PA;b(cFh#~+K(Ca7oCwT#g?-bC)WpAeN<0J^XI{Yvi!e&+`cuTB_sU23> z(FDKt8!%$l4p{up2Lnx%4*xn6KOGD{SBD?Q1M&kY1R#a1{2#opvgAh-w^w!pq!45y=ntwyVQ!{sX9A3ZJ+R-arou$n5zxd6Tj22a zn@*)DQNn=k`TChq#kpoq-p#2Js5s!UVW5;K%K(&A{1k1BM)2Y~qI~8o&?Hmu=9MRdm3e zeMbk`fDWS1uPm*ut}pO?BQZqrZD!HL2ImS64Z(6)x>^fcf>6cE+R1g3tH%(<$S=00 zKhgv+;J|=wP&}aw`40A-pg2*Sn+dLkE5eSRE>Du%W1*3tZ6f+*L`Okmd{GFLknVZ1dK z#1_uN;P0xO!1=}l-~Y3Dhr@{S=Etn{HEFrtJv za|9H_+MK|~TKKsZ%YvB9%*xsYYvux2BpRU20W6FtX@2o_|F?z;vW{vkk_Ca;4^%{} zv>|+j5rw^(F+%(bqNg>dw`qsqFrt9@#fb_-h*E#t|6}EUnHd1ZvgLBnaX}Jy69$HoUH+S_kcK;5C&xJ*WNN}oFLu1?<8L+3`~@0}enyKnVg za_;rwgV|GZ!XYwoAENNkC!sjgtXo0osSrU5}CO} zE8QcebQV75+{a=kbnBjNiP|=tW@;x*b*4b^a$T6ojolV(PE{v6Ai26*bGIvIoIa6IJM>;7|JvZgdFys8d0s)K{D|@ZjznhwF)w^L*|mMN z*L5VK(&D+ri}@3-?@4CJC~8U~rx>dEkxDmNM5K5WRc3V|Er(3w4^!z-*r0L)AXlGP z#&RUv4|I!;vv!u{ou<4`b)0U@=!*sAk!;Ma?M-3lLXnWmpJ4A4gF?L%pvFsY{WK&< z>-+T6vOc$X>L$BX!P`>O(U28iD=S|wzY6?qd$rhgMH1RB8P9+o?!B$AX$$P#%we#Q7M2Oh7AQdE(*K&UyJjTete=a_IiuLvA6pRcU1r}e1;y!`LlFq8J@ix?49#+yKRSQ zavyg@-FE){yLjmP?~AhqnPR{(I`DuKPk#Fv)>G4lp=DQOw45B3dF!FiK`cA&K4LU) z_j zu0Ge#%oM6}&dvZMK^DA^vg3-V8yh-5;P@8WTl8ldR;CY)lHccNeM8o8zgz0n=^2@o zdy;;Vx9)tirsK24{q4#`kL~o z3Ow^+-#XG-@!AT1LGfdyR*Xysv@RN-;k~@!=2XbDt$SN8cS}7~;4tgw%KM^5-B#@WT1iyu zQ(U~SuhQ`6jqXyrS%0%e$vy;{1|>&%oO;i0?|rd+_<q~ zn#&DUDxQ@kG@tC?xEc>Vo_qcf_Oxi`)-vIluJh1x@!_s5*Tyw&$M(FIJ3vF~gvl{2 zy<$SuzCQ`Mbit!|N2tR=<){)3udhOPpuU1hhirSLY728}LPI{OnhdjDOJY6LiM@JX zT3zqTeeDP8-rf+OebFgFa&Yf+qs;iugORrcPGXCz1I)ez?rEfDWy)%S&_3;LZPFGs zXuDM*c*_*>#UbTs(U-Afv8rl(G#{_?T;A#I_=M>KS5{9AqkvQ^SIfxl1qJ@8a2y*i zB*Cp&472dLxh(WV(W$xt`cu{uyW1D4l8)VSb0L*+eh)o3HCmZ(XQg?rkD2Ss*1q!c zx%S}s3umr5yZMyd3}j8q3!hRrmo#^)X6h0G#Tge;5v(^q@bS@9e06-Tf30{**{LJv z%Ws8H_tsrddGthi;BA#+t}JgHb_;9Hz9;x*apl3d0hu?)gzRMA1uZ^fsH*a_nzHzoA%esYA9kCD*brVZ0jR;6VSF4G@%Mn~3@N$}1 zXPhhE3^-W$Y6=a$Qp1{Co5 zP1C@&*gC$|WQ=gVj&C*1B3!TI6I;h8wvKN#OCtQfj&C&=0@s*ze5(l#;d&h(W}QFG z8a@Ny_d!`}wem`UAjlht79z4HT6qT$8-UOW)N8FREU-X01aY2*AW#qyQ#{rUNZ-r^ zk8=PY)_5~ldkZ_P2Smgi=VD?8YJDyc5i3^*OB1}Sy&Wi*K}3MjcEH*~MDVL9U99au zSq~`=5pidO`NU3r^DK(g&hu%fQVS&O;*dH0Hdq5-6{b)tOdaK{St3&X$7wBtwG8F z5h0Y?tZ=TNrfa^=6d+`30xExNEP|^w_*I6%)jIg<<%VB2e!WU{4TlTf#2jmHf(H_? zum*p@8dRO_RyjW|4{GDi{^wlk@toUTdEO-4ii$ z1zC)PnJ3UNAV^a@&KBzcvKVj)g!u!p8P3sjol6|v+yV;(018h)jSzqYA&xb%1DX#J zfr5X{u@+#0QDX-tByzxHeANR?FFkIx=I`QM{K*!gCj&B4yPQ2*{@M>D(Xy*wL zIlit1C)P2XSjTW;BZd<{Aa&P&*S5mp!MOk@$sXvqsU6UHlXVm(>$jL}L;)%sgfl8) z@&lF0nwU($x8RJgZy8Vo!ig2Zt|P&2L;`Li>a+Fweb(#ufqdzQ*|7d`AC@2{hjrq( zbs*e25N;z7j(F1#U~_9XknRHISQnD(I=t&Tyz54I*B@}6>%RjNKoFAW_g@H!6@=)4 zh)MPaE2#in4>-QArY@`gh+sP5V3$qo0TX&Aa;6Xw8DK-!?$R@Hw2%Xq&eR0>l?`YK z=6RFx{X4WuSUb0kXbIO?7jSGLBHwNHng`fGgP6RovaSF!RdZm=4S;ReT>FNw41(=n z<$2AoiL4S@^Bn*a_#+}G4dGw=8l>IY7JzR{hyYkF7HcjIdSxbfLQU2g0$NenjSF1! zpg()=Rrg9GA_ERNIL)g*83y=Kf`}-CLkKxdSOE;UWld0}fSks_p=fb&h$sSlB7jE* zy+z>NL=hM$3Mmfm`o00G)(*D7cdxExW5aP{pK!H)2$nXZqi^4Eaj5z#H*!!tG11ckb-)j720qgGjzb*icfk9Eg&LY7=5Fn~RV?eC} zh5C~P5Xw1!*pB>#`}Je>pSc%BKrtXDLWshlFc5>GMa7|F;)KxdAGPC0pXRSSmcOvQ zer*5WY{OwlC>q4HXb^%T#ZeFhMihz$+Kom7>7)KgtN)<8`3u|Ymf*j$jX*;&NH}oJ zpwbQcLTDrkD!Lj;|D(8nZiW8BAt5~dFUI1#VBtWJAlQau#Gs-mz#$w|6A|b?QHTv3 z5*nkxm~9M}iCvxlzYGzePl6JIpu|y7F_;(x0k#|k(f~9;B}5VblEd{@>@Qpr(uDto z98qFGZlL7~7l%Pb0k^M#x9+r1C=_rDXb2Js&N;}zP-tMM{^)rBFiU^jKHj_tVk_{!ix~l0 z?HHh{NHO4wff68*z&9ZOL=iyQ{>OC6PYvQt5?@V(|BJ+lCm#houQ&p|dalGlGXVt` zgNkAP$P@ofOZpet{#VCEWEUw8WC^MW2%s@QlTk1P6aoJu4c^$Q{7oPG7moj{&stY$ zq!<#4fdlyxd;my2kr)J2RP2xB`@L6A>^rSBzJKBLf90l-XfRR(5@4d<0yzUG@JBHX z=$8M&*8j>kA(0qh`9;5LC=vyZmFOQy(As=$=4L|#yIL9gUmP4H0!Rn-T@wi=OI-Yq zY?ZY+@)u$KuN)8(CI*FpiVzY7+$IRDk#JGK)*qRk@4a_0Ve*fy{9hLEUwzd2aY0}( zzyp8?4~_t~6MTw`f}-OeE#R*j{lBpKU!4`v7J;(@>^w+f(12&4R|qjNVCVlRB>9&! z0-KjW9Od}Wt_lH;JO&hLL46kl*lP)a*dLkGwW)#M4-x#r?*Az1LJ%A&P-+nJL&ZRp ziU3NEK>m@y|9RZt7pDKK%OYwt95?`kIM8H5GypUj1hk@LOrJaikcbgbanj|0pITi1GXE!;hhf&8(s~9x^#l6tpo0#eUGP&+18ne*0RGi2Hv{|7-0t@BcPSyy|+O0i|YghQjgP zzIfe)W}5n1uchHfxVXFY650|qUfyF;FAKi0-fz~V$_)_v;#R41fVKNp&^I|s`c1+lljD zrq{U?8Cy6@W7r`<-CL1SUn+3p#FhjsTel@FxPQ3n7?UD zit!-TfFn>B(j{)gS9cwl5g$t~lL%{l5cCdgP5O3ZSUBp2SINhOXMWT{zoI~w&s{Hgj-e(nBnf5`bCW=HPlB6}5uq)>bpXNERGoI)h87aEzZ?x!7 zkv~VFk)IU(q_UyVZuY#Cb)}y$P7+h$YSwot|K#P?g8U_mX2=C2%JDrOjj2$}Qktn) z3u%wt*OjpMJ+i{c?mcF{ma$~=*|*6Iy+=$ufTdJ0lGU2(hye_*(8hJ0gsjcYd?DDMr4%y4;UM6juN66YP){U0 zm|{CceAh89O>(+&?rEW+yF5iAyLrR>Q#kZ5Hb~E&o_A^t^f(<7W7(p@U8O43CLnXG zr1AZY70hmtrDiJQ9C-e%p)dRIU!+R;=n22>1LrSPhUHh;Tic&dHG91us&T(hem}d5 zUwT$Lo#v$|y#V>Ejpta@FXm)2vOG>>V&Sug-MLfN>9pTcI71-st5@V#Ep`1@s`RwH zY4Zke?s=y(QZ2J2UY`o1CuJ(n2y1R@v-Xl>F(&s4+gX3q+wbD^_FaQTSC|cOQRktD zp0{ufKIkk|-NBW@^3Ley&?MIh>4Dk1b(DdFlb$OJ2@Jf=^^yA)1Kb~6w(>r9<#@qM zN$Ex{F4YTF9lE4rm0RMqb-kW<->lqrQjNZ)rCo)=B059<%CitE{QiJjvFSTAuPH=! zQa`kIP~IWHXSg>sUphM?H~ zM<@y|T{nLOO9Yi#io`|LaB*1=whOKN>~6L)_1oUL#9n1m&ExTFN%x;ze4LHsoz=T& zAo2iLFz{+d9p!rBsdN(gz%#h}JNhh}08eXmHY=SV-U!R?SeomZ0-R*(ES$H7F@9}Z zCyugF>NNPqvb-pH)~fPRlZ0=0IFLskn(`{^^);6fxr+8=rj~>#dCD9v3;Cs6&KCQR z1qBGvM8DC}7AHkIq;82HWwZ%hQiAR)$bdz^N6jUV7k*^ZXxRGFu(smko4(}nzNxgw zY+X~ewLbF`p9jXr#kPgu>X%Y&&(X+v`3o1#?pJkbaX?O?qe$*H6>m)lHoZsxP3w84 z8XsSXQHJNm<(l61bTozb0S+^Dr#&qQ$*3=ot~TY+JW{nL)`oL4QM-DqC(8woP{`FK zX)?cCp)WhdFmU#uirD*)m+snz9XF$T>v<)e=j+R7N1T@LKAFeNC5JBJW=Nr>^NJbO zUqv#P%rSk#G(yfXk0T-_xdVJUlN)}?k z%4vMp3YGEIq!>jp)s6c0`gw9;8fU&sIX?T?h@m(`cDX`mK%=Q}+YY9cxUf-)69-+i z$0@JRUH@?Vz^lj#L93^NvaEERZW#HC^C-%gV0T|<`DUB{Qg-sa6fMaGu~{oi(| zia*`gbm8p|VVA2ErhA@4Tp209jmn63g`f?Q;||($!*_F@#jES^xrrJlSDtCU>7v$t zkoI0=gHJ5($nJu#!BIM|7C#Tn>r`>E?LU||V|-#D!cMn0>*(VI&KIB6TWkeC-f^9@ z9as8tHO8}hdU|wJPs%%$U+F-ds*=pZxlGmRnD_Wym)RJ*mEyGmLM4vF2O46nsZ$qe z3d}DhIF*GZpQ!D9e7OQ%V!;23#gV+)yjCYE$S&wBE{r(=Kmo;7aKV%MFn8HfI|86PH@ zGvyNwY60NxHOCD9y-vM@(fnc?HjQTkeT|r1;TMh%V_Z^geb%#{tE4c;Pg_Km@fB}@g^nKT5O#FNWn z`uO|eR<^|$@AGfEa`zZw_KdyH*lVujhIHs@Au|10lnN*EfWoud~^1_gYd zK2_B&jJ%Q7`Jw*i!d}1VOLq=)?#wiOU`SsTSb63EI;X+K*m?yuP98`yIXiSF?(Ix4 zVnmCX_9L(8vcCnCK{EBL@8c_2$25v>eJu_&ISw9gA!H6$G)`Arkh~}q#fPx3U|h!} zeczc-JD44GFJnEsT%TCn(_Z=*(MMEX$ft-{Heuu_@0%r$Tj7^s@>cuA!m{el^wpOwPeos%ozi_CHoCwYJjG~e>=G+m zZfekxG$-Qa$ZD+6p4g~fEq+TpQDcw`iR6};e??VPHNAzdzUs31?#euxZ?-kpB^QD& z88D%^2SVVxt-Bw9q1@J*?U*^DK#w5%^j(!^!+k(Y1)ou+BV2T zn_pYv6c@sYrMZW7q6}xKj+IY_McxXfN|*_*;eU}fL65lSLFpE^&=IIPS)+$(CQVp2 zaB9y#XuKbP_Z=-anX!&``clz|x;?E|>^D0Q2kfJp+Z`kTt40->VcW>vb34?Nk=43) zkIUIG*|>7Kuh8ux*DeI@{!L?stI;~h9%vBaNEC6%gD^n!Be4JdnBi*d|MQrkI3eZx z_hW_|inzpQZ@wpQtBio$%XFMgOI&@GoHDs|xySstg*FKa${|vg3_uGn~-<{hm;Zf{V3T z)IUmEY@3F-VmwsGgdK>(iZlWyq>1l;CA#sb7uV;B)bUQg( zGV&*JK&Bp^;?bK_pyQsOI@ri+!!y~~mjR>I7C^WEZTox-S)6^`Xa+}!oGFZk5Usuyn340OjiW=xjb--?`i zB*&vsGpN5j{t8#RstH7h(@=g{`IOpxf-7UinvZkJAl;EUrDVW9yz zjJh!wazDF%sSJ)ThMnXf>lv=yO=hXrq$zTFx^sPW?Gs1$bQyi3*AloWo=(-eN6f#-^9>Ft9GXu?UV9HRdodE zeJ%tmTFicmSY94|lS4Ou#OwM3i&WpUD}QE*LBQQ*k#KGy#{MNuY91x1u93llO}Qv^}V*q)nv9WUAWNYGs0I# z{i;#n;F0Rdy-E3Hdy_0B&C9O}k=K*GSEbp;CK#R7GP64Riqs+ zlXLK zxV=GRjjXGKv;b;)?m`UdgD*&%OP(tqdomJkUtaN=DL5k}C`GgFYz^X=;_W?Tm0JzF z7%)207hd*UW-vBN9P%j zZcB@d$l{1duJV#abffD(7%y6r%IMMPkd8=)z%2H)1j{sSFZ6DgQu*v&Czk(3HL~sV zz~kkCT|TorNS+OU7)`wj$(rNJGuui6|MF?ixd@V;qq(hDk>_1oGD!Uewvx-eoZExR z)NOq-xD!MB5o5HNjR^_8&uY%Rv*64VPjBzD?g5mV8ZR$h%DG;*ok8zYzTfVg)~0#V ztwOgAI^(xbT~)_sxIK@nbns(k`N&W^$FsdVi|h;)JaE{RT4$E#_9ZTwX>?}aIWI=G zD>u&^3;xVL$}rAxn5TTAaEObELbQ4O378X6|q&t$VVvOS|B0pR$gcC*okXR?A0e#`QA>a zjPB|i9Mjjsw`Gl(v;~Ea`?Siahp_JSz})nsrWq_M`@|5-!uQk!ne@4==6YB`=6qap z@U%QK{R!H0Amb6;hl^VD-DC|}hgX{Xe9F@^?7b;wG~++3lPabxA0HY%C&GxMca00s zYZSkJCs>@{FS?Ocm!&-_*0HYm09A8}e9GRe;-X?xzy3^DhT9O|ixke6km*k9O+jc* zKgMl}!$rmqUhc@SR_Hjh=bbazJ_or^F8ZHtiNSgHES#xP5t4fp!^PB=XQZVtqc8f# zoQ7FV4(`RzbRs5%MO|cj(@xjk;VtT+-Mu6pEyF%M__N=3T3Jb1vI(Wh72J8E?$$C^ zRI@a#@#JH{wu;vohGTDH(@h)C9#yA2#zbBse5L2QZo2`!4{zuaRfLs4neeVg?P|xn zLl%_Juw2izj_jt_5xtw1)_IZca`6GqYG+Z2@B*WfR~Ao;COXjx9zxag=W@Gp)B`lK zwC)M#D;Xdh@f9hpayE~pWk<*hC)?FwQRh~iP8|pkyBvv4jW8D$=MI>(L?A8~JZ-S( zG}NqVb01icIaU#SIxO#9^nDxgu=CHD6uF~J=xnz#uvMBDso2NW9CGu`y?#a;N>H^K{P_Gpt}| z6G?cJ7X}S%+HZ4_&|8TgluCQbVfVnxP{|m)aOWN=!zcgHgECt6{xZ6rZ6(n`vNkpy zc1gx}Up?PDS30cQCif+RCsn>rF^?g`C@k{Qo5htkWjN)uM8;!kOR9rjkNdqM_CojG zGmh7e9DU4e#E_t_llZAfN8T=>>#kKfiPEzm%^vd7ZQ?aC@31YEQ`^Zj955uZX&x1P zX{;}8kGx4h@?CHlW1qdgjaGXCQht}KqMC~fsU;uBd)_Q{J3YO=jD=wc{Z%jjS=DWr z*VZLdduBPx&xEwbCN~O1J}nm=J(EIfb>R_-Nj0bJ{p}Do2^(H>p;4t4|M1yIMmJde z3u}fxZ=uh?%^1C`8M}1c)p6-$c~eUDvMMGMTI*vr_wlWAVkYY?{uu2At0B3|YRmKD z&(Fzte0o4x6_^zG3dyCq?`vXs!%InqYm!l?tn)2uNHB??>@SDzK2SRQu;t#x!?nkh zoS#O>^58^FE+3GaGSUfl8ahp#?KLV zfXd1$B4&%!j=_bVn=2P-NuJdhB9|)k_uhEq^g+j5~LhKWZ+UEyoy^MPgj7&NgX4g?>WeSa|N^gH)?)B7F%aL5u6>>Lg6kYwr z@XD1B-&m5Cg%#QZ3z*2!6(?nTV7jKXiPg#PMf$fky)i01Y_Ox7#J07ccHe{J&{=ci zEz0;}CQ}K0c3W>@t-1msv08+KuYiNE^!6CPUOtIAo5B&L$${yCNmbi%_DkL>8kQ=# z&Y?_DGL^3iBsSx+UL61wxf%`$fx1G3MiL7%aeV~n=a4<+^`pFwP$WKb5}-XbaJ zgm`_~z$#aBE^6CNf68EX8`fuzF9S~Onh&>ic#u{lVrb<2!gUbUl%40kpjgpL?V4yJ zmT*e!y;7yeo-fxM*`3J_XU9w_fk3FzN5BD6a?EaF@ocaEg_B%Plt&mac*?0G{ex$? zO4y%c7Akxu!YYQDIR%Hrm36GcYzxw{_0er%-D=?_w){Tf*&H-@rRwWfBcAIsI6bt@ zpqMwB8|iRQkfbb(FnEi}Y-e?XZ9B5ZfInmZiWx%W%&|tKs`~jU>ctN|TP#<$O{UTK z8hlly%#sQ|956$dnN-rF2$SpWbdYntVf4mCU&5?S?Z&axCh59%9#1_nezy>1<(`ks zdppW6+zqBiWZ8-AJA8R3iMk*Y1&?yNRoV=b8MTc6zGmBNFqvnL?SWFCrS}?&VhtQ- z;99w2Iq--^i^aKVbj6^1_I~Bg`yMBSRagg}89nShn|~W3_Ok8r8TWG4rQtJ1Y{$;m zUGy79B~?n2OBxxdlh_IewY;3J(*H)P`}+D&>NZXB9RBZ_aK14J;h-2ZRwQ7!(6u`m~ua zTzuoO6(}V9jxquUUQ_d%LITK@|8d2C1xt9;@E?J}#2^&R=xkKh3j4yp|b!xAH|L{xq^T=md5q#L|I;s624r_CSzI5bnmsyCl#{%bZ1*4o18UCZW8qS5+PAp0U8nDv3uvWxwiZ_? zJQSjNAEa_lBaZ(bl_Z4%EaF1{qZ_?k*wfvU6>Uzcl=jcjsMC7$rhay^`ZsuU$W={F zb1i&%!zAo`V|Kv#1<6gd)m8MND@XSS`7d68yyNt5;7jW;luO!=UfDjMOairs&UKgrQe;SxTNj5bhr z$W27{mMP*ESL?p<{nsm!Bp;>SJAWc`s(oO5hZt+Nv{_}$!sAp9)hOLY%Lk3gH}3eh zCbBniaIl3gPtVut8ydab8O`Gijk-Q~+VQk~cXpTcb?$bvF1rJl>X*JUsFZ%A#cI#! zyh*z;f25SUy{5`dsqSwj)UZ*s3>zd7yY@b|q|@WSNv$n~*c+$6H%oC*SWV5f;Y zglAl~Q*&##K;hx}qg6uVYWnqw68kcD%9Q#ZA8f)7UVKEG?YOj0;ea2DL@U)>N5N;) zcZ;C3J_sDHur-Ig0lzP;9e?pzP!T)erRzIl z*!wo%_{44r+8TK9necbQ!;U+iTNlo8h1++IViU{cT~)o~N$aArU+?pu8q|MTRh!c8 zW^=ahz@h$9ny7MmXtSAf$r(GnT#c6K355kjWO0RKPjYjit_`(U#hcNuT~i*Xv|o$-Q*HfQH;KN)@97KDa#gi)Ce&Fy`nDN7G&L zFiHojn(q9H^1D7u6mK)^&c@eq?^fYE{N;fGY1ZxoD&7wh4g4`8QUcK=OVbzOR1}x* zSyU-qq84V_lB|^>*+29JGol%Gh(WX9JdXLsRTs`1FvYadGQJZB8tmMdHIMGf#{2GN z_R;LQ^}=Ui6x*a1_$n`?J4DD^`l-Kmy|d!;Y}Q>A*&VJQ!nj8FZs*T#3%}e&YjxEa3LQdEvR*$mP&e^J=vCU`*7=?{>D@KPVYLQ> zg9Za%X@+^FNdo)O@3sclH@QUV(0Vo`HmH7mOUV-Isvd`W0}-xj*11sXYY^Khl+|1z zz{Y}P^j@%I+b_Cx_Uev9j6BolCJvFd!cMz36?UgxOAhFClc!V|AgLNQINf>h&0_1j zXXRvF%UiUX1DS8kc%($>a43?nu-|XU7X9L;Pu=Z2;~zAEzpQWfLO#GEDqY%YhSI2G zCNeDwLjCB~ z<=awS*8R5st<|DE|a^Er8ZyqEWLsz|9P8jD83LTD=lCdcJxU&2W}-idkXEW}+B$ScFom3|zkX}keW{^3rbE?*3?-L+P$qUkT()ud zsX8LHH1Jg-TeHbj$S9yU)J;te?$NE4q`4i1Clm8L`z6v)h|Z;7tw8a^GP%3;BOAq0 zPHtP;WsS(@AjTC~ht83vWA7(kzh@kp)kwG%p?}%x=60P=&i5p7p8m%g;u!-t^3y9c z*`KI)Txp6o z`MCQ*_lZbtUUI8b$~#amF7b9MIh#2--j+=s%(>1ObF4Tp`|i60t=w8Cfe)iw z9w;7|Rl1_j!;DMZ?v`+&K)6e0tZ#aROFjEAY^H}S-uYCd_W{oGH#EB z$6@ER^Jq@rsv0PlEhuI~4kR%znrYeK?~pNmu_5P(niq9YZkjA>7@R{VzB{TB<<#^b zZmMqr?wd{nyLQ__x2<0n{4q`)0a=TH#!!{Zj~A1 z%YYp`ZL#aNkyinHJ91ZU+H@u9lPx7|GtHb!$DWiNW!M!kI)vszBg>|cVlze0oy2n9 zH0E~~R?@&L&x!hRKP?N-4Pk=5ka_DIJkO0( z-t0Tl>7*jwdPCh@1@YiYx0Aw6hGE%?XOR1drcKkwQ!Ap?=b<@`_ zxRac1EDh@;@fQ(U>bjr7)J|Xc>?@rVBjNbUUdi1?QRTO{UOA~NG1d9*+pA79;rUEz zHqH0qg%q`7ys0OjevLhRQs1eYdf47aQSVerSK+Qy(wGuu4ghZg) zD~|qYyGii!kbDu&Eal7wp7F(+PC~`7Qxx-A~+{0>5 z#3}AwFB?4{kzjG^vX7}_%Cj-}c$dEXEOC-^*BhsnEU2hwKa5AeE#QEZs!enD&B!yp zoQaYicyQ&!Ta|0>dxP&TRTf9$jwf55o(U2}Pj{owvVSA(x#Na=a0BW#Sssw;c8BMq zhKG-+{Ab&<-jw+=XEPrr&D{*=J3CwX0q6H1h^}Ghg-bHe{a>#%oDEms<8^qpLCxcK zyP^CZmAm50wa}GqIiohkzovMrk?(59Rt){UV~YR{z8^vI?^C?hIQr)lZ}t6e|D|J# zfNvV}U1Q`AQ#>$s{)1^kzO%ZDO~9hy*;?>An9X?yXe|D}Vd1|dOTQybc;W^Ovu`Gh zfNko1{*G%=vEL?3U_ksInf?nTr zIfD4s#=qMn6hW~-EBY6%|KK$I6)gNujsp?}9`yikV%kg?0s8~WNbtDJ@6O>*Z(96| zGyGSuga-%yQP!Y}wEB*KU$`c|_VVv!4PGn-o_hWD5U&ov6N?sq!S!Fkf=AdkaQ$QA z{-;^`zZ@g@Y1jZ%pNL}wU}7IUuC@A#OijWQHUB(*4<0z$zz4A~vic~&AIubt=$(!l zDBb1je(unI=!%Sxn^e2Z}6#|P#PK0 z?~?YrO4lqI63iBZYz>bT)sx&3!5l#s&a97b`Kd^7$lzIUhdr_!UYzflbn zdUSPpSA%^D57$wV(!2K=T+ovTK6# zyt{o#&wC}x(??$(SzegO8R;9<_I{n6G`dpdv9v!*KIuTh)j;jKT6Isir-|Wx*0qP2 z?#Au!>B%>&^_uGvVO36l^R<{KQ)mCxfP3*@7b{=1JJ`+UiM)5SOmj7xZMoC5vPC{L zVAAcyNi+M!F+<)M7w;np4r6EI?2(M6aD#7E{Zm)kBl^y5aKo}R<)x>TWphhahN3jGsN$(R%8_VM1xcxQd0_DR8j-8q^QGVFPmb8d6a zkm3E6jHR6p>Fx|u5W2x)E=akwMGSdAC(Nv@D$G^Aw6ePI>g2YV)Rr*=ZQ6#6n2Y@% zq^m6@a20Oig~&^j69c>tQ;ju@t!x@H_KBI9g)HoTo(gL8ub#kT8$My6D3*B zXFQkRk8HCevz#yGw3w`WM%u?IDnWg6;8<>0;#{emY+lZ@Z-%KpA}NRXBBvFv*(k>G zDc@fx(nvCKd`wH{cnWoC=@LbmJ(=QwXoU1~eQ#+tYgsc!-S(yMj-2b^$w@jqU4DK+ zjS<4Q3ALt*JIu4zr#kkdlz38`<-L>i3}QGWyLa^TK8>ccj40)t)GW^a*3bQ9Ybin{ zs0~`GD-@@C_F%7Mr1q%qOEzJ;6V@Q*v1k&hO1jTO0s(>%+% zHC!hw5g01ly|wsUG|hBefAn551?Yo2LqR;B^$TZnpE$M&y0?XU?>zs}d&pgL=B@*D z^8FUfjuShdJ|XeFtaru1g@q!>=*E`rn-a23w!z}|@AL;g3r$R> zeJrGWft*w0)3XJEXX(Sm43dmX^YX#ltIesimHjO8=_wy8b?Hm))P0rnG3^-B!ksH| zW{2~PnROHHNF_5>1|8pm>wT*9cv!HoiPZO0;i25%q2noAJ9^T#opa2kjjA3On)xX3 z@s-OCmz~xVUlvLZEwsxR^3ep!lQa19jfk7?e}Xw_G$rt)M7YUqIa=#*KxAM0r`7`3 z&U^JSY1X!Huy8*A^QWitw|j{T*WZjPiGQJaaM?DI%?mB&(sEOLasCZYTK;8tizx;B zsYy!8{$#h~z|#uW1{o@NoMEa!Pz6hBMSBg0w{1&g<3Q|-)~8HtP!Ty#m1vyjyAQit zZgYzqld^8{jPm@l=c=ibfpif|!xzEGFz>LJPAA9C(TLoklN^I);4g~3(hbf~jeg(b z_a$pm!@DT8KEPjTrQq#>*)JB!#*3P>39_^-pNd}g?agt0n?Za0BRns|lbOrxRI_Ys ztmg2wt2gfoL6%X^6xDZxuh>p(VWPRssy@DbQsVW~9H%{1Rw4ag>tRMvU5T-qkX?A) zV^MBfpBNu35^q%}**`rbbE}j}$P!k0IQB%pD`bb;iQ924+>1p{_xhaLpWl38wG*$Eq!|ty=7zAxn6-USJ&5>tJpIDdDd-O6>hObZn$dE~ zTE?t_g|Hyf=B)a?;RB)07)(D?srx)>Z_C+KwP4l}+b8vU4FzG9Z!4Gw1`y)@zLjRN z?@|iy`_yXfgF2F3Ht&1IZm~GQQ=j3L?PV3lzNqDX43Y7PwmVfvZ|`t%x3N68;Ao3+BN<|3pR!J36HdTT%wIjb^2{hiW$pqY-^936-tPf zXB4+d7p;TK<(`UNsT+-sjWgEDs`)@7co3Cz@A2UjdHcvJt+yFkr zDdlxD7Oos~l8y6od2=}8!|wCqinkAM=L%jp-0~>rdSGiRtHV(NbPV)D1B|S#g`wJw z4l@qP38fb>_b+z8E+3;f=Cdd7z%@Zb_y~8+cBt_9mODjIZ47I~w~F5S){+3WOIFd? zFMFIF)4xbQQPDlt>pzvt!m{+#k1M2M#|^11sEX!tC z%eP;Coxly-^2Uk%RQ5qXZpFFsH?}7)#2yV4=Foqaw@>V3;+&cuh4~;8)Eomfx{hMh z4U>OEwFC97`aQF8+!*~k#tw)0gexM(`?=bW+}g4yv4ok+Q1{Vnu9V>W((Bm~L1Ci@ z=6eRP{IBI!ZrEUybj>8ES;H54I&()fN$we64%2yr4mLgY)wJdS?1}Si;h^iqFRnjrz#l+Fn@+^*hx^kMi;1A)4xla>^!hpr#X4S0l8Gbp>= z+jKAMs?2o8*6T4?gB|H zsgIxRNbsk-+t~KHaZrbtLNbEiY&%<4p|4AqarVW^Qm~kZL+$4xL$veGSo}`1Bg}@} zV^7+f5nm67+IY&q;?e^4X@2QP-#o+0d9D*D;Y=Akz~1_TJ|8o8hoz3adHUWt z$|JI$x1V!WbgAY43MYQ00@Hx%!q%Uy(WdhVT0ft?jKg zFb}ORN9xflIT=w(VL~y%@}7yBI|ZDLd++J9^vUD*V7@eQl~BhGMEQSxVW%-0ktJXC z&4Br(NfSHcnOB;hot0>gb|AN*BxVPzMHfO+`A+WM?spaw%vX|migDO^rt{&KcV@UA z$0U}VxR1t-sqQH$`5au^M}?TKS$>*mgvWIXs-|%7_~2N|eC0+O1gER&$Ck6AIm@fo zH%a650e|PtAR5_Hjd_(*^o-|7>F`rqZ`%S6l_Tfp-|IN!q3)j13gQUgcX`b9%>Aga z<^x!`RI8I10)2ESFi4|9fz^n+u{!Qb3KaI5>x0^($@|HZm2NL}X>E>4F_e^X+8^%> zKb$EyDRv{VQdW>^PWwVKr%=>f@geC80oiOfPS-@`#-cAq9r1hDBPV$^F_t-SC_Jiu zIV`6Pp4wI_*8C;m`l~tB{aJ=ZytNnJxz>b*7<>5KE0uJn?ajRN=9&q|?%;^0ukN2t z7nr$L3+mhTHR!J|9Wd>|?8OfrXbcD`~@=Q7dJ7 za_?Wre_QxuHq{cz@Pg%JW6TVkn<2d@qFi863%5mek$%Si^l9!9>JYPxj9xWUWggUh zl6YP72bqO230`W*Q`T z68ZZu!cP<2zpqrSCN@7;s#c#x|8JG5%}MSmBb$m%fAt(a$l88RRDT1EMiSn>^=n%n z0UpKvXJ8n3VaIRET&piy-k7NVj__Z=!a;iZkAw+D0q_L)ui5qHk$~S2M#2bhkp8ux zu=@7re_;BrV8M$NHZZ**yWW^8Z_KVYq|N{Fd3Ny1kqxAY3H54a;qqNI z$Nku1jzAVn(J-~68EFA_BvCI0G4Blanziq{&+C_G(f9CrmZ3^g-Z!83(l@evAG5g? zO-tL|(h)l8Gne6WFW|__P}5zO9m*X_3%YL^$Hi(I&t73WxJcOwcTHI2Qqy8Nd(M%g zrTBislSE6daGsdjvuB*0VkN#VImrh`Jvw{$#he|7S9+zkNQ8qETYW<9b5F@+#s6dP zEx@|iy8ltSTR=h@l#p&vq&uXfySuwvK)R&6I|ZbX?v(D5Zb1a@z`bzDITWc+MQ^Qmb6hRAl^2aH{K5{H;Ey!K)0Ey4W4 zZN0%Y@p5xRXQh>LQdX2GN3GqP_a3}5ekL(!dIK)PQHOi4dvD8{I4b?lpq#ZO3DL&h zY^apcIP)#AWTUR-%P}8N>|h#Fnjn0^QATONd!NqI5Qs0SC?)!ZW(aYyfhtj%Fw^tY zH`wg93rUD*9?^iZqj`4Vtr@*xAY0@M{-l!+-me!9iw!R0 z?b`sKud_VFt;4gW&YT86|2PlMGfUjnp$Jc(joo5Dm)E`a%-k)sHf#B*#lW1R zT7j7j3wLz6z87y{OtSb~Q>Vo)rbI}A+rE>QH_1vVXsx}(#0w>+9SI>DilvX0?XX$! zCi~sU(5)eLT2(IsIHPz-z{}{%wChWbv=^08A%cD5bO&FE3V;~DG8Rfh@clscLaXO1 zfyLuR#x*&EL%lTqZD#{10>>^d81A+@PCWabt2BXRt8R6lAm8iDbHQ^9 zef|Lb-8|VtrYmPt8U^vDAxy>sI>pOtleiSV8j7(GWHnlxZDT1;l^S*)kx+g>Aw<1U z$55|~MpFkREet0GBm^lJY$Z?w$Pdy>B^Z9eC9YR#*LN6lMhE}wub=#xO!77`w>myY zQFznv9sHz-zNZbNdI7V@``Y9sQk$MFQX`5v2(M;n;kUY;731;GQVx0Ig^pm#WgU$e zP*Pe}_oR@+Dw%9)AHxs6XkUm3iGfWJLctMCIn?%S{)BM5hw@Es@-ek;Om+RRn_Jzq z+`59N#Ejxaj8d9X67LcO`yw0SgBAf`)ZQ4si$T3ZUoNDiz0r7i;^&}Wj$N%-|3)S0uj?7;H< z!B^z;_tge)zm+^MtdM_x#zBjyWR|^vjE>QR<+5b<%|_{vHr0YFXv0nKxI05NzwmS0 zO~1>{n`{P>w_kAOFiGJa&1fNkDBJcr$4zHkXuh>1eIi`QlmmB2&wvldEQ8BN_X#D1 zfS`@h^ermq8)*-6w*5Gy!kiq_cg-OB{ibqZAY}wFD=Rm4v7IGTUs;Z0oS;hf`YhH> zI~>SohSb+EFx4VJ&r~|bc^0820X6mxo@BvdIH1)Y$Z+GODo-ObYd~$je zdWj&L#V~svnM@S~yEN6rie-9|VRE_yegPUY|Lx{%o}RHwhP3>)xW7S;YH*%&@~Kr4 z2wYEh>eTn$-FLCXc{VvzVY*Cf)!W7NfhS_-8}P-12Q?Sqa<9XJppIF-PheR=$&YcB z3CR|Id;R*$?Dy$ix31KI9r&qc_P2|dO;hK*vNdE$c_CBagC+Z14b3mmr-HmGnmMa@ z#655#_%l<_=O`CAXSZ9u+kNJpDj&B+Iv%J|BM}NbmBNayep<6FAMmk!bclU`Z zWAhLim3U7h4n12J{LpB(Ti+wS4h?rj?(*17uEsoT#1GS5H00RYDfw_!3DFqEJv~`w z2rjB3mg^*8a$M;W=}krx<$@Jb@N!XEBqS*E=I0?)II(dXNBS4cjYKk`_(9RjqbFpZ zYL})5jOOxI9dmXBgK`B+jIHO0zTX;BqMGWAY8t<|pMGtW11X3wBX3w@?Kx>`KKSlI z@6HkgA1K^59t%48akE`5*ELek*U}{CW=BguUWtW=+jM)=O;DPc7~4Hr?y&}XaN9zt zBFQuVeM(d%GznwWYT3YI`Oiit9J(4V_6s-N-G~>eCTX0`wzE#`73=eZtMVLf4LC1f zMv_C(%i$Wx;Rb^{;&Os~j>g>GMHqF{-kQXmm^FAmho0GFF#}#V|7ipwfRBlNH=nwR z`jX=7Lg!0-n#T^W)EPH54b3Mf<4)O5_ba*8H1d~%+7Jx(x=qW#|4uOqi6daZ~&mCAV!dX zbpU=OrQjHV@`Zmo0Dnsh{@ww&H^lz#0NkfP|3?nMFG=5fLH<(*;Ab2Dcg#Tfy1VMO zzu3}0ukmI09W#)+1yaAiFyAAk{MDBJFL>!0e>UQO!^{HI-e&mC9BQDj>0hkjyByi? zn1OPREI@Mk=S#lFZ}~S;v-|_^U1hGnyDh)zn3)Brw+5L0KX=UV%e3*|F$1|@CIH^{ zXJ){a`S%_F126p#;NL&fk-zDfft?-b_;*tO2R$MLh*5(@*r=h!lbJ0gM}b)7M|~w+o&oGA2b>(|IF8 zyiMBQRoW-2 zq&0!36^fY`tgN&*7sa82S*SCg3|JlBoaS5zg%{Ce$vt&EE8QC|rLooaUU4+?%&r`Afm_=>9yC z@`s*BmTF`UsmNn=HK}G@W9bW}9^d=cCnh+HdcD(^i6~R7T;fWda2Vavkh0K~&{fF3 zbI7GtvBA|>_)!=p*G&}7!aXa{c@1aG7V5Jjb=_V=D56&E$vk(-0cGVu=hyoPKASx!g!?$GN!~%IU_}l{E!LT z=7dY4^`bY|wVjatyuiXzniA&trVAxwEyYJQwc-=}B9NyR@Y%_XZ`>X2&i41nY9xJ9 z+sIu{w!h(|M1G@kiOet>QK`(Suh})E>Z_jD-?dY#aZ_j36Kc~Wwr4Thf3pygq(&>s zH0za{@|hWHylor5JlJdkP6gUM8k_M^tx`4zApuw-#o&nw!(NSJpbvj*Nk?lkh1`7X zcy^JQ2^}S?)DEKJYlLy^IwH()18=K+B}=p=t}X`H647m2G{Y-vSq>_V-I`rzV+doj z1`(M(n$0gQQ?=*8ejP(|GD5}`JKg57jO)VCk{Q$HTYiE83Hr0<)@80k<1pq~Nr!?t zfx;459n0|TcprtjB!-+^T)`>wy{ZF!i%Lyt48i5H_@DGmBb{RGswvIV zJnAIme)Yc1e$FM2(9{YC>Y@yhVL{jMb!z6p$VceGDHe^)lNJ8jmJFfj3L*h=Q7H&d z&Z&V&&gx-ZT*ax-psl3mvpe`RPmzv2d96i z^(3nbBxD6&rWHg<5qHK8tj?(gm1501=gpdYs;P;k_#`*D;~B@WJG8UKq@qk27Oo5q zq<4ep4kN2j24djbwrJtE;o^J?VBy@3nuMSm^kA^V5pdn0Yz(#wt9+2+ib>D4@R=Om z=Vm`De-BM;2oH}gm;?4Yh7H00!WNeMk=Ua&I8NDo()PB;3T53?XOo=Bxj|Dq1M!uGpj-DdI@akREWew&z*yvo=zPB^ zB8uH6#OI6XcnS`j0(cK-UqnOG!zg)P8-7mLsjAl z>={@~%DPHlUW^ipM`jSeL2qM~qCU%wO-aJppFs0c0=KI&EG;IXXa8~%h^8gMDgb|B zca6m9Y~^&q+biy?1ol!t{aNG@`IG|ZS|q-|GNe3vx;_4&ZW zINDeL*TGZEsrLgy9n<};=w+)C6Gw>-lOn?@ z%Ek#&u38e_=G3uP%fTVxHI=Zk90fQ$kj@E+Aj>&v?4Me7CM0kw1Wn`_ICKv1Eq@+|u1)IU~BPgg?XV4}c zj)8vkdRKTI#$YZktRsjR8`I+XdfwG`MoGd|`Zfz0ryg1m7P(jH&Q8p%lb$w%UXjkjOB0?%Y?x%90!vOUkHvz{+bpM4G)(?rGeB($2d-D(E4~>J z(&@yoYc&`F-XA8S%LmC1+q+y&y;+3zq$}O+vK#_UE=Bt-EF*sh!V#{1M!5htTweF? z`vWCP_*Z){hYiWWLXzJxo%~2jgs{>{e7n1r8%#g8eH{na01vS0x~vxsh zl)Vc3B2Jj321_JU85gA79kai5i0J@ti-VM#%(rmrtb+1hIrBU6y=n^&!9rLZOIR6pw@p|8{SPP z<12EE`;-ACA{vzgf+1Ek;?p(+jh7D*u6Etn)~S{3n9TJqbzYi&%sWE}J){uLu#g}( zwpXJ|B?F1CiV!sCaAq5`d`;wS%(zaIAYd6IKz2^P_L7m~d8J)|2vmtc=lIEEqCV;s z!ZSzvqz|sT@nN1+F<5wPjr|=On0PGLGs^kuT8TG1IMpfa#j;JPslmDOgoy|*@-9hr zjT*D+8;1)rEwtPIIaHbzb~uo^Y8jm-Arcf}H=IPK4K zw0QEczLNn$3recRb!+ImJig~zQbJY4hI>TG@ZBf4B$^h)K}LcU0jpvz1DWxsJerV5 z3W+1wmG-iM0{?$~u@4M0o-w*bvnu`n{3S^6U9Botu6XMfcr+iktqpkj-Oy#YZos z3tIIfE}a|~JKoT-xw;f_yg0mVp5|sBYX3N~lI*Zh^y+q<sxLz`lLk1+pb$#4)83?R z?%~jq;CspxU9~FHz`RqK8CJz(Uo?&omBRWM^(j0N45|0t&N~Y@kwi651%7fH!zJHEv}v zJL|q;29uE7wHBA> zC}KO?O%xyFqVdW%p*5K+OGH8=sT{vss5($X7I~4WH@n;pP&p@;wC$l>Es7{c6s+pR zNStOI)l-A2>Dxl#@Zoj_{4`|$i-IGRu(prIdyA^Vn<(0d1KT!q_WU%Mc#HSf61cA8EVUc zG)lzkK2TfsrjU@Gd80;#d47$?s3ncraI;PI9R<4iLu<6^6W*+ztK&BJTu;bI)V!>j zgj6y3PHWmyzxl^=UFEb@Wk`?e1O_w$q7lgq%QM!v%qEdif>8{##h^o-PUmZuzn6*F zfjEv@%u1c=@Zv>{&J%N)wZUmzR8q19Iw`;fRZn&I1*l%fz7_k|sX z4<}mhN%oV3-DF`no47 zHs$5)XzEupY#p9YsR#lW6Zv`<6IIR(FxX&5;s$d1Rf@M|3E z-c1BNWH?4fY)6dmQTCVgAqKPz?8T(PjQpH5*v{{g;04;wtxo z{AY0}hF?}{|Bm?|3f0|%-u^XE@L%xK|4m!}AT?Y2Lr-_#W2~D2Vn; zbmQk>(0{>u2jlW^i~m7rW+3p!02FrnxnqW3a{j;RnF&DsVff8l{=Zd5|A&tMiT4g? z?B7a#2k*oJOtAP>>YsD|zmb}eg&6=e`GxnFq6z;wEB!A^E`Gzy08GZen>_!k%s)rJ ze#gwn48%u&4MWl2m#O$SqZ+uEzh?&O`2Sl~{}VIAFVWTCiA@h+$N&W*f4*k=Use(Q zH_QNT-oF(azzYD@b^P2f!`}ja4^cZ{u>ZaW;y+KX078*J3L^ez>lOZ1pz}uv?;hUb zKM3JvOTV<>B|@KH+$PZU1wFN1w!${c;G2yo{&E`R-z|GJeoO0TC==D0Ue^aXsDRXh zspmPZeuf`UQrLpa@(!jk(6?7VA8H%Rn{SU(9r z|5D`r7)&&7+#7s9euGQ$*C%3J&*I12T|{!}gN6<{G#;5a$54BrN0#FB@$#>=YrW7< z$4iA>4ezo^!Z~VHG*(z;c4?SRP4M6{9Shek5gG`KA}?js8aZL>I6&Ldu&S4@WtDd< zL7^V4lw^)%z*M=c9?&>17IPl|3>Cw3^)*fn6cN|@qyNJX*e}8T`>Xhg`5)H&(f_hg>AztH0{%ZeG`|rWKn7t4 z9?f4Ln_pfOzhMS2VD6rXpPBDUxBmN{|ACp|Z({%Df&D9T$3x8hKYJ4Iml^$dXZ|sA z?#}!dnAp2U`a2L0Ya3fW06~n94vtn_>tDZtDmQSn3P!rNhBg3t+npH&jHf?Ao*DiC z6akolQ}XNC=vW(B+5&*+49xc``>QE*&wFQ>sSvUN>sr}>d;u!}0>}a^VPpl~hj-Yj ztNkaM1c)Rm;r!ygm+bb z@A-hrs{qF6{eETu3i2Lq7C>3NJD&OOJU|&&79eTF0z6_Y!0bJyyYm8HbT+`!x;yp` zln?;9A*81Rsu}(C55pbQF0e5JyZ)Q)2OsOdcz^uQe0ROTBg+bCko8UqdY{1ZG0a8Egz%{V}*LbftKxeFg?5u#MS%5*u3?w620Nvf`fgRA( z{WSqRcWsP772Y4)!({;|k%Y`ZqLk@w1MUVhFdOeqBTPVL<~uy+JFNn6$N-uo0MZN0 z2xI_C7Tp03vj7@k0_;lwy%mrUI3CdE{ha{jFERsn>~0?`FzW7q-<=DXBFG46`z~F| z0wjj+w0EZ!wLi1Oe_L1h=f~pCG6KfhA2iVY9|$);8UV1UKTvLdGyo`me?Z*;gAVRr zm9NQ&UdvMR=vrvsLy}Vim6bUN`6MJnfaQe1Z#p_SGBQ4EJplUM!kk~rR*wVt$N@t{ z)Xo&ZPb8#c@|cC(Uf-&b8D0N-0%&%nt1k7q{2T;GC_ z^^ayS^lpO>*tdT0=QE5 zfbQgfXzG{!T4qM3PX9W>!pzdn763GtumE7q0Z7@u%c-FEht4GQbdBuHe%>o$t7U4W z!((n>sz*o-80LUOaDR11HiAZudb+QTY;_C?^|efG^zPe%59Lp%zkBE0%RwtF%me(P z`q!d3Fr^rH^6sup$IjYX&)oKYtO08KLF*d6^fivF@y~Y`$Q&+! zq_BAspX=M-6d%R1yV57~ z7t0xk+n<_)6B*P6`BWA(8{|Gybr)5)Wb!{M3V=}SsudK>B&~(9m|Eq1OvLr*2`2^$ zkLsEnp<(EB>!@S+u3@7q8uPbHyh09^qD{fT_5&xS@7H;*L`qJLTPs8C|%h0 z!JEX2G@XXoiYmK$FrUTg%DGZY$C(u7i{<;9IUTXX#uTuZ9nyoRxi+5i)OP5nT89&s zl8bqqQBri0Y4jEy*`kEMzRJ*~u~vH3(A;KjZN64=>0-~&Af>^~scLXD%9SgVmF*Jd zad7mR2`^9sjst#qYLy+^QouRZ{nqztQku3x6H6A?5c8oFO9YA5)7+>0wQPjNzuEh4D<8KKCV z39yJmIrG=wOLJz2VIxS+cE<}DLn={b#Y<2bodZLs6D@?1(K^)79T>{|?EfkLBIu=N@v z6kBUr_7ML~R(^cSk)=~}dnM7=6|IYL#*aLQliMxri6`uOq#^0Gyr$zZbIjbdXsNj< zf~;c2SrUBkY8OdKPt9|_8TlsDl+6vlx+DW(6(L+Ij79}{lhXhEX?xWCn|xG08-od$M~~98AQnTrK;sNIqAV~dZ{mwx7B z;e+n9JHyN%#Lr%6om!Myo}FuAAbvt93>HBsrOVBC7N@Z#d|Zx}r*~5K_^p!rs`L5n zIV*;gyB>bQc|sD_RLfygg?ot>#vq;I;V49grE$bS465@hwlYrevBWh#PCk{4>J=gq z3-q{8W z_lEdi1K595toU&?|3mK)uz`N^9szITzU9u``K$K`_02kIcYi#s7c% z|E>-m{Kmg6nET;3vivJX@u%MiIQ4&VBmuvXnpO|MVJx@CmK1g{dhJr2FAW0zuY4j{74( z@uL|C9no590dAnFp1$p$2Ll;_KU#k}m=S0;wR`YRfv^v)j)j?-)&nOqA+4d4rJ
rK}K<{D?6wtf) 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 literal 0 HcmV?d00001 diff --git a/doc/dev_guide.txt b/doc/dev_guide.txt new file mode 100644 index 0000000..c7e9b54 --- /dev/null +++ b/doc/dev_guide.txt @@ -0,0 +1,432 @@ +================================================================ +Guide pour le développement d'un module SALOME 2 en Python +================================================================ + +:Auteur: Caremoli C. + +.. contents:: +.. sectnum:: + +Présentation +========================= +Ce document a pour objectif de décrire les différentes étapes +du développement d'un module SALOME 2 en Python. +Il commence par un bref rappel des principes de SALOME 2. Puis, il décrit +les étapes successives qui seront suivies pour arriver à une configuration +de module complète. + +Rappels sur les modules et composants SALOME 2 +================================================== +Dans son principe, la plate-forme SALOME 2 est décomposée en une plate-forme +de base nommée module KERNEL et une collection de modules divers. + +Un module est un produit compilable et installable qui se concrétise par une arborescence source qui doit +respecter les règles générales SALOME2 et qui comprend une procédure de construction, installation qui +respecte également les règles SALOME2. +Chaque module est géré en configuration dans un module CVS +indépendant. Chaque module peut livrer des versions à son rythme dans le respect des règles de +cohérence de SALOME2. A chaque module est associée une base de tests de non régression. + +Un module a des dépendances avec les autres modules (utilise, est utilisé). +Le module KERNEL constitue la base de la plate-forme SALOME2. +Tous les autres modules dépendent du module KERNEL. + +===================================== ========= ============= ================================== +Sous projets Modules Utilise Est utilisé par +===================================== ========= ============= ================================== +SP1 - Environnement de production +SP2 - Architecture KERNEL MED, GEOM, SMESH, VISU,SUPERV +SP2 - Architecture MED KERNEL SMESH, VISU +SP3 - Géométrie GEOM KERNEL SMESH +SP5 - Maillage SMESH KERNEL, MED +SP6 - Superviseur SUPERV KERNEL +SP7 - Visualisation VISU KERNEL, MED +===================================== ========= ============= ================================== + +Un module contient un ou plusieurs composants SALOME. Un composant SALOME est un objet CORBA qui +respecte les règles SALOME et qui est déclaré à SALOME au moyen d'un catalogue. Un composant SALOME +peut être doté d'une interface utilisateur graphique (GUI) qui doit elle-même respecter les règles +SALOME. + +Les étapes de construction du module exemple +==================================================== +Le module exemple choisi pour illustrer le processus de construction d'un +module est extrèmement simple. Il contiendra un seul composant et ce composant +aura un seul service nommé getBanner qui acceptera une chaine de caractères +comme unique argument et qui retournera une chaine de caractères obtenue +par concaténation de "Hello " et de la chaine d'entrée. Ce composant sera +complété par un GUI graphique écrit en PyQt. + +Les différentes étapes du développement seront les suivantes : + + - créer une arborescence de module + - créer un composant SALOME 2 chargeable par un container Python + - configurer le module pour que le composant soit connu de SALOME + - ajouter un GUI graphique + - rendre le composant utilisable dans le superviseur + +Création de l'arborescence du module +======================================= +Dans un premier temps, on se contentera de mettre dans le module exemple un composant +SALOME écrit en Python qui sera chargeable par un container Python. +Il suffit donc d'une interface idl et d'une implantation Python du composant. +Pour mettre en oeuvre ceci dans un module SALOME 2, il faut l'arborescence de +fichier suivante:: + + + PYHELLO1_SRC + + build_configure + + configure.in.base + + Makefile.in + + adm_local + + unix + + make_commence.in + + make_omniorb.in + + config_files + + bin + + VERSION + + runAppli.in + + runSalome.py + + idl + + Makefile.in + + PYHELLO_Gen.idl + + src + + Makefile.in + + PYHELLO + + Makefile.in + + PYHELLO.py + + doc + +Le module a pour nom PYHELLO1_SRC et le composant PYHELLO. +Tous les fichiers sont indispensables à l'exception de VERSION, runAppli et runSalome.py. +VERSION sert pour documenter le module, il doit donner sa version et ses compatibilités ou +incompatibilités avec les autres modules. Il est donc fortement recommandé mais pas indispensable +au fonctionnement. +Les fichiers runAppli et runSalome.py ne sont pas indispensables mais facilitent la mise en +oeuvre de l'exemple. + +Mise en garde : il ne faut pas copier les fichiers de la plate-forme de base (KERNEL) pour +initialiser une arborescence de module. Il est, en général, préférable de copier les fichiers +d'un autre module comme GEOM ou MED. + +Mise en oeuvre d'autoconf, configure +-------------------------------------- +SALOME utilise autoconf pour construire le script configure qui sert à l'installation pour +tester la configuration du système et pour préconfigurer les fichiers Makefile de contruction +du module. +Le fichier build_configure contient une procédure qui à partir de configure.in.base et au moyen +d'autoconf construit le script configure. +Tous les fichiers dont l'extension est in sont des squelettes qui seront transformés par le +processus de configure. + +Presque tous les fichiers utilisés pour ce processus sont localisés dans la plate-forme de +base qui est référencée par la variable d'environnement KERNEL_ROOT_DIR. Cependant quelques +fichiers doivent être modifiés en fonction du module cible. C'est le cas bien sur de build_configure +et de configure.in.base qui doivent en général adaptés. + +Les fichiers de base pour le configure du module KERNEL et des autres modules sont rassemblés +dans le répertoire salome_adm du module KERNEL. Il faut cependant, pour pouvoir utiliser les objets +CORBA du module KERNEL surcharger les fichiers make_commence.in et make_omniorb.in du répertoire +salome_adm. Cette surcharge est réalisée en mettant les fichiers make_commence.in et make_omniorb.in +modifiés dans le répertoire adm_local du module exemple. + +config_files est un répertoire dans lequel on peut mettre les fichiers m4 qui servent à tester +la configuration du système dans le processus de configure. Si les fichiers de salome_adm ne sont pas +suffisants, on peut en ajouter dans adm_local. + +Répertoire idl +------------------ +Dans le répertoire idl, il faut un Makefile qui doit mettre en oeuvre la compilation +du fichier idl PYHELLO_Gen.idl et installer tous ces fichiers dans les bons répertoires +de l'installation du module. Il suffit de modifier la cible IDL_FILES pour obtenir +un fichier adapté. + +Concernant le fichier idl lui-même, il doit définir un module CORBA dont le nom +doit être différent du nom du module pour éviter les conflits de nom et définir une +interface CORBA qui dérive à minima de l'interface Component du module Engines. +Le nom du module CORBA sera PYHELLO_ORB et le nom de l'interface PYHELLO_Gen. + +Répertoire src +------------------ +Le répertoire src contiendra tous les composants et GUI graphiques du module. Chacune +de ces entités doit avoir son propre répertoire. + +Le module ne contiendra pour le moment qu'un seul répertoire pour le moteur du +composant PYHELLO et son nom sera PYHELLO. + +Le Makefile se contente de déclencher le parcours des sous répertoires qui sont +décrits par la cible SUBDIRS. + +Répertoire PYHELLO +''''''''''''''''''''''' +Le répertoire contient le module Python qui représente le composant et donc contient la classe PYHELLO +et un fichier Makefile dont le rôle est simplement d'exporter le module PYHELLO.py +dans le répertoire d'installation du module SALOME. + +Le module PYHELLO.py contient la classe PYHELLO qui dérive de l'interface PYHELLO_Gen du +module CORBA PYHELLO_ORB__POA et de la classe SALOME_ComponentPy_i du module SALOME_ComponentPy. + +Répertoire doc +------------------ +Il ne contient rien pour le moment. Il pourrait contenir ce document. + +Répertoire bin +------------------ +VERSION sert pour documenter le module, il doit donner sa version et ses compatibilités ou +incompatibilités avec les autres modules. Il est donc fortement recommandé mais pas indispensable +au fonctionnement. + +Le fichier runAppli.in est l'équivalent du runSalome du module KERNEL configuré pour mettre +en oeuvre le module KERNEL et ce module PYHELLO. + +Le fichier runSalome.py est le fichier du module KERNEL avec une correction de bug pour +tourner seulement avec un container Python, une modification de la fonction test qui crée +le composant PYHELLO au lieu d'un composant MED et un développement pour disposer de +la complétion automatique en Python. + +Création d'un composant chargeable par un container +====================================================== +Les fichiers présentés ci-dessus suffisent pour construire et installer le module PYHELLO1_SRC, +lancer la plate-forme SALOME constituée des modules KERNEL et PYHELLO1 et demander au container +Python le chargement d'un composant PYHELLO. + +Toutes les étapes suivantes supposent que les logiciels prérequis de SALOME sont accessibles dans l'environnement +du développeur de modules. + +Construction, installation +--------------------------------- +Dans PYHELLO1_SRC, faire:: + + export KERNEL_ROOT_DIR= + ./build_configure + +Aller dans ../PYHELLO1_BUILD et faire:: + + ../PYHELLO1_SRC/configure --prefix= + make + make install + +Lancement de la plate-forme +------------------------------- +Aller dans et faire:: + + ./bin/salome/runAppli + +Cette commande lance SALOME configurée pour KERNEL et le module PYHELLO1. A la fin de ce +lancement l'utilisateur est devant un interpréteur Python configuré pour SALOME et qui +donne accès aux objets CORBA de SALOME. + +runAppli est un shell qui exécute un script Python en lui passant des arguments en ligne de +commande:: + + python -i $PYHELLO_ROOT_DIR/bin/salome/runSalome.py --modules=PYHELLO --xterm --containers=cpp,python --killall + +Ces arguments indiquent que l'on prendra le script runSalome.py situé dans le module PYHELLO, que l'on +activera le composant PYHELLO, les impressions seront redirigées dans une fenêtre xterm, on lancera un +container Python et tous les processus SALOME existant avant le lancement seront tués. + +Pour que cette commande fonctionne, il faut préalablement avoir positionné les variables d'environnement +suivantes:: + + export KERNEL_ROOT_DIR= + export PYHELLO_ROOT_DIR= + +Cette méthode d'activation des modules et composants de SALOME 2 tend à confondre module et composant. +Dans ce cas (1 composant par module), il n'y a pas de difficulté à paramétrer le lancement. Il suffit d'indiquer derrière +l'option --modules la liste des composants demandés (KERNEL est inutile) et de fournir autant de variables +d'environnement qu'il y a de composants. Le nom de ces variables doit être _ROOT_DIR et doit donner le chemin +du module contenant le composant. Dans le cas où on a plusieurs composants par module, c'est un peu plus +compliqué. Ce sera présenté ultérieurement. + +Mise en garde: il est possible que le lancement de SALOME 2 n'aille pas jusqu'au bout. En effet +dans certaines circonstances, le temps de lancement des serveurs CORBA peut être long et dépasser +le timeout fixé à 21 secondes. Si la raison en est le temps de chargement important des +bibliothèques dynamiques, il est possible qu'un deuxième lancement dans la foulée aille +jusqu'au bout. + +Chargement du composant exemple +------------------------------------ +Pour avoir accès aux méthodes du composant, il faut importer le module PYHELLO_ORB avant +de demander le chargement du composant au container Python. Ce container Python +a été rendu accessible dans runSalome.py au moyen de la variable container:: + + import PYHELLO_ORB + c=container.load_impl("PYHELLO","PYHELLO") + c.makeBanner("Christian") + +La dernière instruction doit retourner 'Hello Christian'. +Pour voir les objets CORBA créés par ces actions, faire:: + + clt.showNS() + +On peut voir que le composant a été créé et enregistré dans un contexte de nommage qui peut +être incorrect en raison d'un bug identifié dans la version 1.2.1 du module KERNEL. + + +Composant SALOME déclaré +============================== +Pour le moment, le composant PYHELLO a été chargé en faisant une requête directe au container +Python. Ce n'est pas la méthode standard pour charger un composant. La voie normale passe +par le service LifeCycle qui utilise les services du catalogue pour identifier le composant +et ses propriétés puis appelle le container demandé pour charger le composant. + +Pour pouvoir utiliser cette méthode, il faut déclarer le composant dans un catalogue au format XML dont le +nom doit être Catalog.xml. Dans notre cas ce sera PYHELLOCatalog.xml. Ce catalogue sera rangé +dans le répertoire resources. Arborescence actualisée:: + + + PYHELLO1_SRC + + build_configure + + configure.in.base + + Makefile.in + + adm_local + + bin + + idl + + src + + doc + + resources + + PYHELLOCatalog.xml + +En dehors de l'ajout du répertoire resources et du fichier PYHELLOCatalog.xml, le reste des fichiers +est identique. Il faut cependant modifier le Makefile.in de tête pour que le catalogue soit bien installé +dans le répertoire d'installation. Il suffit de le spécifier dans la cible RESOURCES_FILES. + +Construction, installation +--------------------------------- +Il n'est pas nécessaire de refaire un configure pour prendre en compte cette modification. Il +suffit d'aller dans PYHELLO1_BUILD et de faire:: + + ./config.status + make + make install + +Lancement de la plate-forme +------------------------------- +Le lancement de la plate-forme se passe de la même manière que précédemment. Aller dans PYHELLO1_INSTALL et faire:: + + ./bin/salome/runAppli + +Chargement du composant exemple +------------------------------------ +La méthode de chargement du composant n'est pas très différente de la fois précédente. On +utiilise maintenant les services du module LifeCycle au lieu d'appeler directement le container. +La séquence d'appel est contenue dans la fonction test de runSalome.Py. :: + + c=test(clt) + c.makeBanner("Christian") + +La fonction test crée le LifeCycle. Puis elle demande le chargement du composant PYHELLO +dans le container FactoryServerPy:: + + def test(clt): + """ + Test function that creates an instance of PYHELLO component + usage : pyhello=test(clt) + """ + import LifeCycleCORBA + lcc = LifeCycleCORBA.LifeCycleCORBA(clt.orb) + import PYHELLO_ORB + pyhello = lcc.FindOrLoadComponent("FactoryServerPy", "PYHELLO") + return pyhello + +Chargement depuis l'interface applicative (IAPP) +---------------------------------------------------------- +Pour pouvoir charger dynamiquement un composant en utilisant la barre à composants +de l'IAPP, il faut déclarer l'icone représentative du composant dans le catalogue. +Pour la déclarer il suffit d'ajouter une ligne pour l'icone au catalogue du composant:: + + PYHELLO.png + +et de mettre le fichier correspondant dans le répertoire resources du module. + +Pour tester la bonne configuration de la barre à composants, lancer SALOME 2 comme +précédemment puis à partir de l'interpréteur Python lancer l'IAPP par:: + + startGUI() + +et charger le composant en cliquant sur l'icone de PYHELLO après avoir ouvert une étude. L'IAPP doit +signaler que le GUI du composant n'est pas correctement configuré mais le composant sera quand +même créé après un temps d'attente. On peut le constater en tapant:: + + clt.showNS() + +Ajout d'un GUI graphique +=========================== +L'étape suivante pour compléter le module consiste à ajouter au composant PYHELLO +une interface graphique qui sera écrite en Python en utilisant la bibliothèque de +widgets Qt. Cette interface graphique doit s'intégrer dans l'interface applicative +de SALOME (IAPP) et doit donc respecter certaines contraintes que nous allons voir. + +Tout d'abord, précisons le contour du GUI d'un composant. +Le comportement du GUI est +donné par un module Python dont le nom est normalisé GUI.py. Il doit +proposer des points d'entrée conventionnels qui seront utilisés par l'IAPP pour activer +ce GUI ou l'informer de certains évènements. +L'activation des commandes du GUI est réalisée au moyen d'une barre de menu et d'une barre +à boutons qui s'intègrent dans la barre à menus et dans la barre à boutons de l'IAPP. + + +Module Python implantant le comportement du GUI +----------------------------------------------------- +Le comportement du GUI du composant PYHELLO est implanté dans le module Python PYHELLOGUI.py +du sous-répertoire PYHELLOGUI. +Le Makefile.in localisé dans le répertoire src doit être actualisé pour parcourir le sous-répertoire PYHELLOGUI. +Un Makefile.in doit être ajouté dans le sous-répertoire PYHELLOGUI. Les cibles +importantes sont PO_FILES et EXPORT_PYSCRIPTS. + +La cible EXPORT_PYSCRIPTS doit être mise à jour avec le nom des modules Python à rendre visible +dans Salome, c'est à dire principalement pour qu'ils soient importables (commande import de Python). + +La cible PO_FILES doit être mise à jour avec les noms des fichiers qui sont utilisés pour le multi-linguisme. +Pour le moment le fichier PYHELLO_msg_en.po (traduction pour langue anglaise) est vide car le multi-linguisme +n'est pas mis en oeuvre dans cet exemple. + +Barre à menus et barre à boutons +---------------------------------- +Les barres à menus et à boutons du composant PYHELLO sont décrites dans un fichier au format XML +pour permettre leur chargement dynamique dans l'IAPP. Ce fichier est localisé dans le répertoire resources +du module et a un nom standardisé _en.xml pour la langue anglaise. Pour la langue française, il +faut également un fichier de nom _fr.xml. +Pour le composant PYHELLO, le fichier PYHELLO_en.xml contient un menu avec un item et un bouton. +L'icone du bouton est fournie par le fichier ExecPYHELLO.png localisé dans le répertoire resources du module. + +Etapes ultérieures restant à décrire +========================================== + + - lien avec l'étude + - lien avec la sélection + - ajout d'un popup contextuel + - comment rendre le composant supervisable + - ajout de la persistance + - avoir plusieurs composants dans le même module + +Rapides rappels sur l'architecture SALOME 2 +================================================== +Les containers +-------------------- +Dans SALOME, les composants sont dynamiquement chargeables. Cette propriété est obtenu +en utilisant un mécanisme de container. + +Dans ses grandes lignes, un container est un serveur CORBA dont l'interface dispose +des méthodes nécessaires pour effectuer le chargement déchargement de l'implantation +d'un composant SALOME. Pour effectuer le chargement d'un composant, on appellera la méthode +load_impl du container. + +La mécanique de base du chargement d'un composant est dépendante du langage d'implantation choisi. + +En C++, la plate-forme utilise le chargement dynamique de bibliothèque (dlopen) et un mécanisme de fonction +factory dont le nom doit être Engine_factory (par exemple GEOMEngine_factory, pour GEOM). +Cette fonction doit retourner l'objet CORBA effectif qui est le composant SALOME. + +En Python, la plate-forme utilise le mécanisme d'import de Python (import ) et instancie +le composant SALOME Python en utilisant une classe (ou une factory) de même nom () pour +ce faire. + +Le multi-linguisme +----------------------- +A compléter + +Les logiciels prérequis +--------------------------- +A compléter + + + diff --git a/idl/Makefile.in b/idl/Makefile.in new file mode 100644 index 0000000..366defb --- /dev/null +++ b/idl/Makefile.in @@ -0,0 +1,60 @@ +# +# generate dependencies for idl file : +# + +# source path +top_srcdir=@top_srcdir@ +top_builddir=.. +srcdir=@srcdir@ +VPATH=.:$(srcdir):${KERNEL_ROOT_DIR}/idl/salome + +@COMMENCE@ + +IDL_FILES = PYHELLO_Gen.idl + +PY_CLIENT_IDL = $(IDL_FILES) + +# we copy all idl file in $(top_builddir)/idl +inc: $(IDL_FILES:%=$(top_builddir)/idl/%) + +$(IDL_FILES:%=$(top_builddir)/idl/%):$(top_builddir)/idl/%:% + #$(CP) $< $@ + cp -f $< $@ + +lib: pyidl + +PYTHON_BUILD_SITE=$(top_builddir)/lib/python$(PYTHON_VERSION)/site-packages/@PACKAGE@ + +pyidl: $(PYTHON_BUILD_SITE) $(IDL_FILES:%.idl=$(PYTHON_BUILD_SITE)/%_idl.py) + +$(PYTHON_BUILD_SITE): + $(INSTALL) -d $@ + +$(PYTHON_BUILD_SITE)/%_idl.py: %.idl + $(OMNIORB_IDL) $(OMNIORB_IDLPYFLAGS) -C$(PYTHON_BUILD_SITE) $< + +# install python client (generated from idl file +install: install-pyidl install-idl + +# create directory $(idldir) and copy idl files into it +install-idl: $(IDL_FILES) + $(INSTALL) -d $(idldir) + cp -p $^ $(idldir) + +install-pyidl: $(IDL_FILES) + $(INSTALL) -d $(PYTHON_SITE_INSTALL) + @for file in $^ dummy; do \ + if [ $$file != "dummy" ]; then \ + $(OMNIORB_IDL) $(OMNIORB_IDLPYFLAGS) -C$(PYTHON_SITE_INSTALL) $$file ; \ + fi ; \ + done ; + + +cleandep: + -$(RM) .dep* + +distclean: + -$(RM) *.py + -$(RM) $(IDL_FILES:%=$(top_builddir)/idl/%) + -$(RM) Makefile + diff --git a/idl/PYHELLO_Gen.idl b/idl/PYHELLO_Gen.idl new file mode 100644 index 0000000..8757320 --- /dev/null +++ b/idl/PYHELLO_Gen.idl @@ -0,0 +1,17 @@ +#ifndef __PYHELLO_GEN__ +#define __PYHELLO_GEN__ + +#include "SALOME_Component.idl" +#include "SALOME_Exception.idl" + +module PYHELLO_ORB +{ + interface PYHELLO_Gen : Engines::Component + { + string makeBanner(in string name) + raises (SALOME::SALOME_Exception); + }; +}; + +#endif + diff --git a/resources/ExecPYHELLO.png b/resources/ExecPYHELLO.png new file mode 100644 index 0000000000000000000000000000000000000000..16a20c116e8243a6b49ed862613d2cc49bdf4caa GIT binary patch literal 831 zcmV-F1Hk-=P)A+3!%gdoE?w?yY*XMamxaAW~()k6;QGVVf3ZPpQcy+38CrH3{Qk zoaxN-vWJ+OcH(Y#5qvHK|CitMf1CdUU;7AQ8zF4-#i736F~#EMso~pq*Ek7JMLa$}POH_T(b)M|f)>8t;^3f3 zKA)#ntMKyW+7Z-s>l6xWsZ53jrMAEC5{41RXe`Snj$`6DMr+Vop|xgsc$hE@Sz20V zb@eG)%b|Y+_m{*NND_%L1}POFH@MUObOdhQq^%&CMdWZvC2q+x@_Pg_JQ$DGG%bJbwIyVzG#2o#E=$@5yGf z#Bm5%IplY1BB@I((}Bdlpj1;;nAaqNZEDBWHP2)F0;K|LMcrchIBe@ z&Ye4p5H>e&{)pCc=qTd1Z_6|q4IIZIpUy{Fg7-dG2KQ=nb2l+s9A+3!%gdoE?w?yY*XMamxaAW~()k6;QGVVf3ZPpQcy+38CrH3{Qk zoaxN-vWJ+OcH(Y#5qvHK|CitMf1CdUU;7AQ8zF4-#i736F~#EMso~pq*Ek7JMLa$}POH_T(b)M|f)>8t;^3f3 zKA)#ntMKyW+7Z-s>l6xWsZ53jrMAEC5{41RXe`Snj$`6DMr+Vop|xgsc$hE@Sz20V zb@eG)%b|Y+_m{*NND_%L1}POFH@MUObOdhQq^%&CMdWZvC2q+x@_Pg_JQ$DGG%bJbwIyVzG#2o#E=$@5yGf z#Bm5%IplY1BB@I((}Bdlpj1;;nAaqNZEDBWHP2)F0;K|LMcrchIBe@ z&Ye4p5H>e&{)pCc=qTd1Z_6|q4IIZIpUy{Fg7-dG2KQ=nb2l+s9 + + + + + + + + + + + + + + PYHELLO + PYHELLO GUI + Data + C. Caremoli + 1.0 + EDF - RD + 1 + PYHELLO.png + 'linux' ~ OS + + + + diff --git a/resources/PYHELLO_en.xml b/resources/PYHELLO_en.xml new file mode 100644 index 0000000..048c191 --- /dev/null +++ b/resources/PYHELLO_en.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 0000000..1742b11 --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,20 @@ +#============================================================================== +# File : Makefile.in +# Created : ven déc 7 13:32:20 CET 2001 +# Author : Paul RASCLE, EDF +# Project : SALOME +# Copyright : EDF 2001 +# $Header$ +#============================================================================== + +# source path +top_srcdir=@top_srcdir@ +top_builddir=.. +srcdir=@srcdir@ +VPATH=.:@srcdir@ + +@COMMENCE@ + +SUBDIRS = PYHELLO PYHELLOGUI + +@MODULE@ diff --git a/src/PYHELLO/Makefile.in b/src/PYHELLO/Makefile.in new file mode 100644 index 0000000..bb52cee --- /dev/null +++ b/src/PYHELLO/Makefile.in @@ -0,0 +1,20 @@ +# source path +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl:${KERNEL_ROOT_DIR}/idl/salome + +@COMMENCE@ + +EXPORT_PYSCRIPTS = \ +PYHELLO.py + +# Libraries targets + +LIB_SERVER_IDL = +LIB_CLIENT_IDL = + +# Executables targets + +@CONCLUDE@ + diff --git a/src/PYHELLO/PYHELLO.py b/src/PYHELLO/PYHELLO.py new file mode 100644 index 0000000..f27c680 --- /dev/null +++ b/src/PYHELLO/PYHELLO.py @@ -0,0 +1,25 @@ +import PYHELLO_ORB__POA +import SALOME_ComponentPy + +class PYHELLO(PYHELLO_ORB__POA.PYHELLO_Gen, + SALOME_ComponentPy.SALOME_ComponentPy_i): + """ + Pour etre un composant SALOME cette classe Python + doit avoir le nom du composant et heriter de la + classe PYHELLO_Gen issue de la compilation de l'idl + par omniidl et de la classe SALOME_ComponentPy_i + qui porte les services generaux d'un composant SALOME + """ + def __init__ (self, orb, poa, contID, containerName, instanceName, + interfaceName): + print "PYHELLO.__init__: ",containerName,' ',instanceName + SALOME_ComponentPy.SALOME_ComponentPy_i.__init__(self, orb, poa, + contID, containerName,instanceName, interfaceName, 0 ) + # On stocke dans l'attribut _naming_service, une reference sur + # le Naming Service CORBA + self._naming_service=SALOME_ComponentPy.SALOME_NamingServicePy_i(self._orb) + + def makeBanner(self,name): + banner= "Hello %s" % name + return banner + diff --git a/src/PYHELLOGUI/Makefile.in b/src/PYHELLOGUI/Makefile.in new file mode 100644 index 0000000..6e01cf9 --- /dev/null +++ b/src/PYHELLOGUI/Makefile.in @@ -0,0 +1,26 @@ +# source path +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl:${KERNEL_ROOT_DIR}/idl/salome + +@COMMENCE@ + +# header files +EXPORT_HEADERS= + +# .po files to transform in .qm +PO_FILES = PYHELLO_msg_en.po PYHELLO_icons.po + +# Libraries targets + +LIB = +LIB_SRC = + +LIB_CLIENT_IDL = + +LIB_SERVER_IDL = + +EXPORT_PYSCRIPTS=PYHELLOGUI.py + +@CONCLUDE@ diff --git a/src/PYHELLOGUI/PYHELLOGUI.py b/src/PYHELLOGUI/PYHELLOGUI.py new file mode 100644 index 0000000..8f81e8d --- /dev/null +++ b/src/PYHELLOGUI/PYHELLOGUI.py @@ -0,0 +1,76 @@ +import qt +from qt import * +import traceback + +# Global variable to store Salome Workspace +WORKSPACE=None + +import SalomePyQt +# Communication with Salome : desktop, signal and slots +sgPyQt=SalomePyQt.SalomePyQt() +desktop=sgPyQt.getDesktop() + +# LifeCycle and component PYHELLO +import salome +lifecycle = salome.lcc +import PYHELLO_ORB +pyhello=lifecycle.FindOrLoadComponent("FactoryServerPy", "PYHELLO") + +def setWorkSpace(pyws): + global WORKSPACE + print "setWorkSpace: ",pyws + WORKSPACE=pyws + +def OnGUIEvent(commandID) : + print "PYHELLOGUI::OnGUIEvent::commandID,WORKSPACE= ",commandID,WORKSPACE + if dict_command.has_key(commandID): + try: + r=dict_command[commandID](WORKSPACE) + print r + except: + traceback.print_exc() + else: + print "Pas de commande associée a : ",commandID + +def setSettings(): + print "setSettings" + +def activeStudyChanged(ID): + print "activeStudyChanged: ",ID + +def definePopup(theContext, theObject, theParent): + print "PYHELLOGUI --- definePopup: ",theContext,theObject,theParent + +def customPopup(popup, theContext, theObject, theParent): + print "PYHELLOGUI --- customPopup: ",theContext,theObject,theParent + +class MyDialog(qt.QDialog): + def __init__(self,parent=None, name=None, modal=0, flags=0): + qt.QDialog.__init__(self,parent, name, modal, flags) + self.vb = qt.QVBoxLayout(self, 8) + self.vb.setAutoAdd(1) + self.hb0 = qt.QHBox(self) + label=QLabel("Prenom",self.hb0) + self.entry=QLineEdit( self.hb0) + + self.hb = qt.QHBox(self) + c = qt.QPushButton("OK", self.hb) + self.connect(c, qt.SIGNAL('clicked()'), self.accept) + d = qt.QPushButton("CANCEL", self.hb) + self.connect(d, qt.SIGNAL('clicked()'), self.reject) + +def ExecPYHELLO(ws): + # Modal dialog, parent desktop + w=MyDialog(desktop,"Name",1) + # Wait answer + r=w.exec_loop() + if r == QDialog.Accepted: + name=str(w.entry.text()) + banner=pyhello.makeBanner(name) + QMessageBox.about(desktop,'Salome Example',banner) + else: + print "CANCEL" + +dict_command={ + 941:ExecPYHELLO, + } diff --git a/src/PYHELLOGUI/PYHELLO_icons.po b/src/PYHELLOGUI/PYHELLO_icons.po new file mode 100644 index 0000000..b386757 --- /dev/null +++ b/src/PYHELLOGUI/PYHELLO_icons.po @@ -0,0 +1,11 @@ +# This is a Qt message file in .po format. Each msgid starts with +# a scope. This scope should *NOT* be translated - eg. "Foo::Bar" +# would be translated to "Pub", not "Foo::Pub". +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2002-05-28 10:57:43 AM CEST\n" +"PO-Revision-Date: YYYY-MM-DD\n" +"Last-Translator: FULLNAME \n" +"Content-Type: text/plain; charset=iso-8859-1\n" + diff --git a/src/PYHELLOGUI/PYHELLO_msg_en.po b/src/PYHELLOGUI/PYHELLO_msg_en.po new file mode 100644 index 0000000..b386757 --- /dev/null +++ b/src/PYHELLOGUI/PYHELLO_msg_en.po @@ -0,0 +1,11 @@ +# This is a Qt message file in .po format. Each msgid starts with +# a scope. This scope should *NOT* be translated - eg. "Foo::Bar" +# would be translated to "Pub", not "Foo::Pub". +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2002-05-28 10:57:43 AM CEST\n" +"PO-Revision-Date: YYYY-MM-DD\n" +"Last-Translator: FULLNAME \n" +"Content-Type: text/plain; charset=iso-8859-1\n" + -- 2.30.2