# HG changeset patch # User Roeland Merks # Date 2010-06-09 16:14:29 # Node ID e7eab96321ce07473c953ca77e720a9462ffc16d # Parent aaba9e8828d6f0e601cd4e138bb34e4b8b75ea04 Added finalized tutorial code. Added new header files that provide simplified constructs for summing up concentrations in walls. Also added a new function for resetting all walls of a cell. New menu items in canvas for resetting chemical values only in cells or only in walls. -- user: Roeland Merks branch 'default' added src/TutorialCode/Tutorial1A/mymodel.cpp added src/TutorialCode/Tutorial1A/mymodel.h added src/TutorialCode/Tutorial1A/mymodel.pro added src/TutorialCode/Tutorial1B/mymodel.cpp added src/TutorialCode/Tutorial1B/mymodel.h added src/TutorialCode/Tutorial1B/mymodel.pro added src/TutorialCode/Tutorial1C/mymodel.cpp added src/TutorialCode/Tutorial1C/mymodel.h added src/TutorialCode/Tutorial1C/mymodel.pro added src/TutorialCode/Tutorial1D/mymodel.cpp added src/TutorialCode/Tutorial1D/mymodel.h added src/TutorialCode/Tutorial1D/mymodel.pro added src/TutorialCode/Tutorial3/tutorial3_init.xml added src/TutorialCode/Tutorial4/auxin_growth_init.xml added src/TutorialCode/Tutorial4/mymodel added src/TutorialCode/Tutorial4/tutorial4_init.xml added src/TutorialCode/Tutorial5/mymodel added src/TutorialCode/Tutorial5/tutorial5_init.xml added src/flux_function.h added src/vleafmodel.h changed src/Makefile changed src/TutorialCode/Tutorial2/mymodel.cpp changed src/TutorialCode/Tutorial3/mymodel.cpp changed src/TutorialCode/Tutorial4/mymodel.cpp changed src/TutorialCode/Tutorial4/mymodel.h changed src/TutorialCode/Tutorial5/mymodel.cpp changed src/TutorialCode/Tutorial5/mymodel.h changed src/VirtualLeaf.pro changed src/cellbase.cpp changed src/cellbase.h diff --git a/src/Makefile b/src/Makefile --- a/src/Makefile +++ b/src/Makefile @@ -1,27 +1,854 @@ -# $Id: Makefile,v 3f0977faba37 2010/06/03 15:54:37 michael $ +############################################################################# +# Makefile for building: ../bin/VirtualLeaf +# Generated by qmake (2.01a) (Qt 4.4.1) on: Wed Jun 9 16:00:42 2010 +# Project: VirtualLeaf.pro +# Template: app +# Command: /ufs/merks/Trolltech/Qt-4.4.1/bin/qmake -unix -o Makefile VirtualLeaf.pro +############################################################################# + +####### Compiler, tools and options + +CC = gcc +CXX = g++ +DEFINES = -DQTGRAPHICS -DREACTIONS_HEADER= -DREACTIONS_HEADER_STRING="" -DFLEMING -DQT_NO_DEBUG -DQT_QT3SUPPORT_LIB -DQT3_SUPPORT -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED +CFLAGS = -m64 -pipe -O2 -D_REENTRANT -Wall -W $(DEFINES) +CXXFLAGS = -m64 -pipe -fexceptions -fPIC -I/usr/include/libxml2 -DQTGRAPHICS -O2 -D_REENTRANT -Wall -W $(DEFINES) +INCPATH = -I../../../Trolltech/Qt-4.4.1/mkspecs/linux-g++-64 -I. -I../../../Trolltech/Qt-4.4.1/include/QtCore -I../../../Trolltech/Qt-4.4.1/include/QtCore -I../../../Trolltech/Qt-4.4.1/include/QtGui -I../../../Trolltech/Qt-4.4.1/include/QtGui -I../../../Trolltech/Qt-4.4.1/include/Qt3Support -I../../../Trolltech/Qt-4.4.1/include/Qt3Support -I../../../Trolltech/Qt-4.4.1/include -I. -I. +LINK = g++ +LFLAGS = -m64 -fPIC -Wl,-rpath,/ufs/merks/Trolltech/Qt-4.4.1/lib +LIBS = $(SUBLIBS) -L/ufs/guravage/opt/qwt-5.2.1-svn/lib -L/ufs/merks/Trolltech/Qt-4.4.1/lib -lxml2 -lQt3Support -L/ufs/merks/Trolltech/Qt-4.4.1/lib -lQtSql -pthread -pthread -pthread -pthread -lQtXml -pthread -pthread -pthread -pthread -L/usr/X11R6/lib64 -pthread -pthread -pthread -pthread -pthread -pthread -lQtNetwork -pthread -pthread -pthread -pthread -pthread -pthread -lQtGui -pthread -lpng -lSM -lICE -pthread -pthread -lXi -lXrender -lXrandr -lfreetype -lfontconfig -lXext -lX11 -lQtCore -lz -lm -pthread -lgthread-2.0 -lrt -lglib-2.0 -ldl -lpthread +AR = ar cqs +RANLIB = +QMAKE = /ufs/merks/Trolltech/Qt-4.4.1/bin/qmake +TAR = tar -cf +COMPRESS = gzip -9f +COPY = cp -f +SED = sed +COPY_FILE = $(COPY) +COPY_DIR = $(COPY) -r +INSTALL_FILE = install -m 644 -p +INSTALL_DIR = $(COPY_DIR) +INSTALL_PROGRAM = install -m 755 -p +DEL_FILE = rm -f +SYMLINK = ln -sf +DEL_DIR = rmdir +MOVE = mv -f +CHK_DIR_EXISTS= test -d +MKDIR = mkdir -p + +####### Output directory + +OBJECTS_DIR = ./ + +####### Files -QMAKE = qmake +SOURCES = apoplastitem.cpp \ + canvas.cpp \ + cellbase.cpp \ + cell.cpp \ + cellitem.cpp \ + mainbase.cpp \ + matrix.cpp \ + mesh.cpp \ + miscq.cpp \ + modelcatalogue.cpp \ + Neighbor.cpp \ + node.cpp \ + nodeitem.cpp \ + nodeset.cpp \ + OptionFileDialog.cpp \ + output.cpp \ + parameter.cpp \ + pardialog.cpp \ + parse.cpp \ + random.cpp \ + rungekutta.cpp \ + simitembase.cpp \ + transporterdialog.cpp \ + UniqueMessage.cpp \ + vector.cpp \ + wallbase.cpp \ + wall.cpp \ + wallitem.cpp \ + warning.cpp \ + xmlwritecode.cpp \ + xmlwrite.cpp \ + VirtualLeaf.cpp moc_canvas.cpp \ + moc_cellbase.cpp \ + moc_cell.cpp \ + moc_infobar.cpp \ + moc_modelcatalogue.cpp \ + moc_OptionFileDialog.cpp \ + moc_pardialog.cpp \ + moc_transporterdialog.cpp \ + moc_UniqueMessage.cpp +OBJECTS = apoplastitem.o \ + canvas.o \ + cellbase.o \ + cell.o \ + cellitem.o \ + mainbase.o \ + matrix.o \ + mesh.o \ + miscq.o \ + modelcatalogue.o \ + Neighbor.o \ + node.o \ + nodeitem.o \ + nodeset.o \ + OptionFileDialog.o \ + output.o \ + parameter.o \ + pardialog.o \ + parse.o \ + random.o \ + rungekutta.o \ + simitembase.o \ + transporterdialog.o \ + UniqueMessage.o \ + vector.o \ + wallbase.o \ + wall.o \ + wallitem.o \ + warning.o \ + xmlwritecode.o \ + xmlwrite.o \ + VirtualLeaf.o \ + moc_canvas.o \ + moc_cellbase.o \ + moc_cell.o \ + moc_infobar.o \ + moc_modelcatalogue.o \ + moc_OptionFileDialog.o \ + moc_pardialog.o \ + moc_transporterdialog.o \ + moc_UniqueMessage.o +DIST = ../../../Trolltech/Qt-4.4.1/mkspecs/common/g++.conf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/common/unix.conf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/common/linux.conf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/qconfig.pri \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/qt_functions.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/qt_config.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/exclusive_builds.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/default_pre.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/release.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/default_post.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/qt.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/unix/thread.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/moc.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/warn_on.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/resources.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/uic.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/yacc.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/lex.prf \ + VirtualLeaf.pro +QMAKE_TARGET = VirtualLeaf +DESTDIR = ../bin/ +TARGET = ../bin/VirtualLeaf -all: VirtualLeaf libplugin plugins +first: all +####### Implicit rules + +.SUFFIXES: .o .c .cpp .cc .cxx .C + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o "$@" "$<" + +####### Build rules + +all: Makefile $(TARGET) + +$(TARGET): $(OBJECTS) + @$(CHK_DIR_EXISTS) ../bin/ || $(MKDIR) ../bin/ + $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS) -VirtualLeaf: Makefile.VirtualLeaf - make -f Makefile.VirtualLeaf +Makefile: VirtualLeaf.pro ../../../Trolltech/Qt-4.4.1/mkspecs/linux-g++-64/qmake.conf ../../../Trolltech/Qt-4.4.1/mkspecs/common/g++.conf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/common/unix.conf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/common/linux.conf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/qconfig.pri \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/qt_functions.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/qt_config.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/exclusive_builds.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/default_pre.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/release.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/default_post.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/qt.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/unix/thread.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/moc.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/warn_on.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/resources.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/uic.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/yacc.prf \ + ../../../Trolltech/Qt-4.4.1/mkspecs/features/lex.prf \ + /ufs/merks/Trolltech/Qt-4.4.1/lib/libQt3Support.prl \ + /ufs/merks/Trolltech/Qt-4.4.1/lib/libQtSql.prl \ + /ufs/merks/Trolltech/Qt-4.4.1/lib/libQtCore.prl \ + /ufs/merks/Trolltech/Qt-4.4.1/lib/libQtXml.prl \ + /ufs/merks/Trolltech/Qt-4.4.1/lib/libQtGui.prl \ + /ufs/merks/Trolltech/Qt-4.4.1/lib/libQtNetwork.prl + $(QMAKE) -unix -o Makefile VirtualLeaf.pro +../../../Trolltech/Qt-4.4.1/mkspecs/common/g++.conf: +../../../Trolltech/Qt-4.4.1/mkspecs/common/unix.conf: +../../../Trolltech/Qt-4.4.1/mkspecs/common/linux.conf: +../../../Trolltech/Qt-4.4.1/mkspecs/qconfig.pri: +../../../Trolltech/Qt-4.4.1/mkspecs/features/qt_functions.prf: +../../../Trolltech/Qt-4.4.1/mkspecs/features/qt_config.prf: +../../../Trolltech/Qt-4.4.1/mkspecs/features/exclusive_builds.prf: +../../../Trolltech/Qt-4.4.1/mkspecs/features/default_pre.prf: +../../../Trolltech/Qt-4.4.1/mkspecs/features/release.prf: +../../../Trolltech/Qt-4.4.1/mkspecs/features/default_post.prf: +../../../Trolltech/Qt-4.4.1/mkspecs/features/qt.prf: +../../../Trolltech/Qt-4.4.1/mkspecs/features/unix/thread.prf: +../../../Trolltech/Qt-4.4.1/mkspecs/features/moc.prf: +../../../Trolltech/Qt-4.4.1/mkspecs/features/warn_on.prf: +../../../Trolltech/Qt-4.4.1/mkspecs/features/resources.prf: +../../../Trolltech/Qt-4.4.1/mkspecs/features/uic.prf: +../../../Trolltech/Qt-4.4.1/mkspecs/features/yacc.prf: +../../../Trolltech/Qt-4.4.1/mkspecs/features/lex.prf: +/ufs/merks/Trolltech/Qt-4.4.1/lib/libQt3Support.prl: +/ufs/merks/Trolltech/Qt-4.4.1/lib/libQtSql.prl: +/ufs/merks/Trolltech/Qt-4.4.1/lib/libQtCore.prl: +/ufs/merks/Trolltech/Qt-4.4.1/lib/libQtXml.prl: +/ufs/merks/Trolltech/Qt-4.4.1/lib/libQtGui.prl: +/ufs/merks/Trolltech/Qt-4.4.1/lib/libQtNetwork.prl: +qmake: FORCE + @$(QMAKE) -unix -o Makefile VirtualLeaf.pro + +dist: + @$(CHK_DIR_EXISTS) .tmp/VirtualLeaf1.0.0 || $(MKDIR) .tmp/VirtualLeaf1.0.0 + $(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/VirtualLeaf1.0.0/ && $(COPY_FILE) --parents apoplastitem.h canvas.h cellbase.h cell.h cellitem.h infobar.h mainbase.h mainbase.h matrix.h mesh.h miscq.h modelcatalogue.h Neighbor.h node.h nodeitem.h nodeset.h OptionFileDialog.h output.h parameter.h pardialog.h parse.h pi.h qcanvasarrow.h random.h rungekutta.h simitembase.h simplugin.h sqr.h tiny.h transporterdialog.h UniqueMessage.h vector.h wallbase.h wall.h wallitem.h warning.h xmlwrite.h flux_function.h vleafmodel.h VirtualLeafpar.tmpl .tmp/VirtualLeaf1.0.0/ && $(COPY_FILE) --parents apoplastitem.cpp canvas.cpp cellbase.cpp cell.cpp cellitem.cpp mainbase.cpp matrix.cpp mesh.cpp miscq.cpp modelcatalogue.cpp Neighbor.cpp node.cpp nodeitem.cpp nodeset.cpp OptionFileDialog.cpp output.cpp parameter.cpp pardialog.cpp parse.cpp random.cpp rungekutta.cpp simitembase.cpp transporterdialog.cpp UniqueMessage.cpp vector.cpp wallbase.cpp wall.cpp wallitem.cpp warning.cpp xmlwritecode.cpp xmlwrite.cpp VirtualLeaf.cpp .tmp/VirtualLeaf1.0.0/ && (cd `dirname .tmp/VirtualLeaf1.0.0` && $(TAR) VirtualLeaf1.0.0.tar VirtualLeaf1.0.0 && $(COMPRESS) VirtualLeaf1.0.0.tar) && $(MOVE) `dirname .tmp/VirtualLeaf1.0.0`/VirtualLeaf1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/VirtualLeaf1.0.0 + + +clean:compiler_clean + -$(DEL_FILE) $(OBJECTS) + -$(DEL_FILE) *~ core *.core + + +####### Sub-libraries + +distclean: clean + -$(DEL_FILE) $(TARGET) + -$(DEL_FILE) Makefile + + +mocclean: compiler_moc_header_clean compiler_moc_source_clean + +mocables: compiler_moc_header_make_all compiler_moc_source_make_all + +compiler_moc_header_make_all: moc_canvas.cpp moc_cellbase.cpp moc_cell.cpp moc_infobar.cpp moc_modelcatalogue.cpp moc_OptionFileDialog.cpp moc_pardialog.cpp moc_transporterdialog.cpp moc_UniqueMessage.cpp +compiler_moc_header_clean: + -$(DEL_FILE) moc_canvas.cpp moc_cellbase.cpp moc_cell.cpp moc_infobar.cpp moc_modelcatalogue.cpp moc_OptionFileDialog.cpp moc_pardialog.cpp moc_transporterdialog.cpp moc_UniqueMessage.cpp +moc_canvas.cpp: simitembase.h \ + mainbase.h \ + mesh.h \ + cell.h \ + vector.h \ + sqr.h \ + parameter.h \ + wall.h \ + wallbase.h \ + warning.h \ + cellbase.h \ + node.h \ + random.h \ + modelelement.h \ + Neighbor.h \ + simplugin.h \ + cellitem.h \ + infobar.h \ + nodeitem.h \ + data_plot.h \ + curvecolors.h \ + canvas.h + /ufs/merks/Trolltech/Qt-4.4.1/bin/moc $(DEFINES) $(INCPATH) canvas.h -o moc_canvas.cpp + +moc_cellbase.cpp: vector.h \ + sqr.h \ + parameter.h \ + wall.h \ + wallbase.h \ + warning.h \ + cellbase.h + /ufs/merks/Trolltech/Qt-4.4.1/bin/moc $(DEFINES) $(INCPATH) cellbase.h -o moc_cellbase.cpp -Makefile.VirtualLeaf: VirtualLeaf.pro - $(QMAKE) -makefile -o $@ $< +moc_cell.cpp: vector.h \ + sqr.h \ + parameter.h \ + wall.h \ + wallbase.h \ + warning.h \ + cellbase.h \ + cell.h + /ufs/merks/Trolltech/Qt-4.4.1/bin/moc $(DEFINES) $(INCPATH) cell.h -o moc_cell.cpp + +moc_infobar.cpp: infobar.h + /ufs/merks/Trolltech/Qt-4.4.1/bin/moc $(DEFINES) $(INCPATH) infobar.h -o moc_infobar.cpp + +moc_modelcatalogue.cpp: warning.h \ + cell.h \ + vector.h \ + sqr.h \ + parameter.h \ + wall.h \ + wallbase.h \ + cellbase.h \ + mesh.h \ + node.h \ + random.h \ + modelelement.h \ + Neighbor.h \ + simplugin.h \ + canvas.h \ + simitembase.h \ + mainbase.h \ + cellitem.h \ + infobar.h \ + nodeitem.h \ + data_plot.h \ + curvecolors.h \ + modelcatalogue.h + /ufs/merks/Trolltech/Qt-4.4.1/bin/moc $(DEFINES) $(INCPATH) modelcatalogue.h -o moc_modelcatalogue.cpp + +moc_OptionFileDialog.cpp: OptionFileDialog.h + /ufs/merks/Trolltech/Qt-4.4.1/bin/moc $(DEFINES) $(INCPATH) OptionFileDialog.h -o moc_OptionFileDialog.cpp + +moc_pardialog.cpp: pardialog.h + /ufs/merks/Trolltech/Qt-4.4.1/bin/moc $(DEFINES) $(INCPATH) pardialog.h -o moc_pardialog.cpp + +moc_transporterdialog.cpp: transporterdialog.h + /ufs/merks/Trolltech/Qt-4.4.1/bin/moc $(DEFINES) $(INCPATH) transporterdialog.h -o moc_transporterdialog.cpp + +moc_UniqueMessage.cpp: UniqueMessage.h + /ufs/merks/Trolltech/Qt-4.4.1/bin/moc $(DEFINES) $(INCPATH) UniqueMessage.h -o moc_UniqueMessage.cpp + +compiler_rcc_make_all: +compiler_rcc_clean: +compiler_image_collection_make_all: qmake_image_collection.cpp +compiler_image_collection_clean: + -$(DEL_FILE) qmake_image_collection.cpp +compiler_moc_source_make_all: +compiler_moc_source_clean: +compiler_uic_make_all: +compiler_uic_clean: +compiler_yacc_decl_make_all: +compiler_yacc_decl_clean: +compiler_yacc_impl_make_all: +compiler_yacc_impl_clean: +compiler_lex_make_all: +compiler_lex_clean: +compiler_clean: compiler_moc_header_clean + +####### Compile + +apoplastitem.o: apoplastitem.cpp canvas.h \ + simitembase.h \ + mainbase.h \ + mesh.h \ + cell.h \ + vector.h \ + sqr.h \ + parameter.h \ + wall.h \ + wallbase.h \ + warning.h \ + cellbase.h \ + node.h \ + random.h \ + modelelement.h \ + Neighbor.h \ + simplugin.h \ + cellitem.h \ + infobar.h \ + nodeitem.h \ + data_plot.h \ + curvecolors.h \ + apoplastitem.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o apoplastitem.o apoplastitem.cpp + +canvas.o: canvas.cpp pardialog.h \ + parameter.h \ + vector.h \ + sqr.h \ + canvas.h \ + simitembase.h \ + mainbase.h \ + mesh.h \ + cell.h \ + wall.h \ + wallbase.h \ + warning.h \ + cellbase.h \ + node.h \ + random.h \ + modelelement.h \ + Neighbor.h \ + simplugin.h \ + cellitem.h \ + infobar.h \ + nodeitem.h \ + data_plot.h \ + curvecolors.h \ + nodeset.h \ + wallitem.h \ + xmlwrite.h \ + miscq.h \ + OptionFileDialog.h \ + modelcatalogue.h \ + psb.xpm \ + cwi.xpm + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o canvas.o canvas.cpp -libplugin: Makefile.libplugin - make -f Makefile.libplugin +cellbase.o: cellbase.cpp nodeitem.h \ + simitembase.h \ + node.h \ + vector.h \ + sqr.h \ + random.h \ + parameter.h \ + cell.h \ + wall.h \ + wallbase.h \ + warning.h \ + cellbase.h \ + modelelement.h \ + Neighbor.h \ + cellitem.h \ + qcanvasarrow.h \ + nodeset.h \ + mesh.h \ + simplugin.h \ + tiny.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o cellbase.o cellbase.cpp + +cell.o: cell.cpp cell.h \ + vector.h \ + sqr.h \ + parameter.h \ + wall.h \ + wallbase.h \ + warning.h \ + cellbase.h \ + node.h \ + random.h \ + modelelement.h \ + Neighbor.h \ + mesh.h \ + simplugin.h \ + tiny.h \ + nodeset.h \ + cellitem.h \ + simitembase.h \ + nodeitem.h \ + qcanvasarrow.h \ + canvas.h \ + mainbase.h \ + infobar.h \ + data_plot.h \ + curvecolors.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o cell.o cell.cpp + +cellitem.o: cellitem.cpp cellitem.h \ + simitembase.h \ + cell.h \ + vector.h \ + sqr.h \ + parameter.h \ + wall.h \ + wallbase.h \ + warning.h \ + cellbase.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o cellitem.o cellitem.cpp + +mainbase.o: mainbase.cpp mainbase.h \ + mesh.h \ + cell.h \ + vector.h \ + sqr.h \ + parameter.h \ + wall.h \ + wallbase.h \ + warning.h \ + cellbase.h \ + node.h \ + random.h \ + modelelement.h \ + Neighbor.h \ + simplugin.h \ + xmlwrite.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o mainbase.o mainbase.cpp + +matrix.o: matrix.cpp vector.h \ + sqr.h \ + matrix.h \ + tiny.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o matrix.o matrix.cpp + +mesh.o: mesh.cpp mesh.h \ + cell.h \ + vector.h \ + sqr.h \ + parameter.h \ + wall.h \ + wallbase.h \ + warning.h \ + cellbase.h \ + node.h \ + random.h \ + modelelement.h \ + Neighbor.h \ + simplugin.h \ + tiny.h \ + pi.h \ + parse.h \ + matrix.h \ + nodeset.h \ + nodeitem.h \ + simitembase.h \ + rungekutta.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o mesh.o mesh.cpp -Makefile.libplugin: libplugin.pro - $(QMAKE) -makefile -o $@ $< +miscq.o: miscq.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o miscq.o miscq.cpp + +modelcatalogue.o: modelcatalogue.cpp modelcatalogue.h \ + warning.h \ + cell.h \ + vector.h \ + sqr.h \ + parameter.h \ + wall.h \ + wallbase.h \ + cellbase.h \ + mesh.h \ + node.h \ + random.h \ + modelelement.h \ + Neighbor.h \ + simplugin.h \ + canvas.h \ + simitembase.h \ + mainbase.h \ + cellitem.h \ + infobar.h \ + nodeitem.h \ + data_plot.h \ + curvecolors.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o modelcatalogue.o modelcatalogue.cpp + +Neighbor.o: Neighbor.cpp Neighbor.h \ + cell.h \ + vector.h \ + sqr.h \ + parameter.h \ + wall.h \ + wallbase.h \ + warning.h \ + cellbase.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o Neighbor.o Neighbor.cpp + +node.o: node.cpp node.h \ + vector.h \ + sqr.h \ + random.h \ + parameter.h \ + cell.h \ + wall.h \ + wallbase.h \ + warning.h \ + cellbase.h \ + modelelement.h \ + Neighbor.h \ + mesh.h \ + simplugin.h \ + pi.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o node.o node.cpp + +nodeitem.o: nodeitem.cpp nodeitem.h \ + simitembase.h \ + node.h \ + vector.h \ + sqr.h \ + random.h \ + parameter.h \ + cell.h \ + wall.h \ + wallbase.h \ + warning.h \ + cellbase.h \ + modelelement.h \ + Neighbor.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o nodeitem.o nodeitem.cpp + +nodeset.o: nodeset.cpp nodeset.h \ + node.h \ + vector.h \ + sqr.h \ + random.h \ + parameter.h \ + cell.h \ + wall.h \ + wallbase.h \ + warning.h \ + cellbase.h \ + modelelement.h \ + Neighbor.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o nodeset.o nodeset.cpp + +OptionFileDialog.o: OptionFileDialog.cpp OptionFileDialog.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o OptionFileDialog.o OptionFileDialog.cpp + +output.o: output.cpp warning.h \ + parameter.h \ + vector.h \ + sqr.h \ + output.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o output.o output.cpp + +parameter.o: parameter.cpp parameter.h \ + vector.h \ + sqr.h \ + output.h \ + parse.h \ + xmlwrite.h \ + warning.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o parameter.o parameter.cpp + +pardialog.o: pardialog.cpp pardialog.h \ + parameter.h \ + vector.h \ + sqr.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o pardialog.o pardialog.cpp -plugins: - make -C build_models +parse.o: parse.cpp warning.h \ + parse.h \ + output.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o parse.o parse.cpp + +random.o: random.cpp random.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o random.o random.cpp + +rungekutta.o: rungekutta.cpp rungekutta.h \ + warning.h \ + maxmin.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o rungekutta.o rungekutta.cpp + +simitembase.o: simitembase.cpp simitembase.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o simitembase.o simitembase.cpp + +transporterdialog.o: transporterdialog.cpp canvas.h \ + simitembase.h \ + mainbase.h \ + mesh.h \ + cell.h \ + vector.h \ + sqr.h \ + parameter.h \ + wall.h \ + wallbase.h \ + warning.h \ + cellbase.h \ + node.h \ + random.h \ + modelelement.h \ + Neighbor.h \ + simplugin.h \ + cellitem.h \ + infobar.h \ + nodeitem.h \ + data_plot.h \ + curvecolors.h \ + transporterdialog.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o transporterdialog.o transporterdialog.cpp + +UniqueMessage.o: UniqueMessage.cpp UniqueMessage.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o UniqueMessage.o UniqueMessage.cpp + +vector.o: vector.cpp sqr.h \ + pi.h \ + vector.h \ + tiny.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o vector.o vector.cpp + +wallbase.o: wallbase.cpp wall.h \ + wallbase.h \ + vector.h \ + sqr.h \ + node.h \ + random.h \ + parameter.h \ + cell.h \ + warning.h \ + cellbase.h \ + modelelement.h \ + Neighbor.h \ + mesh.h \ + simplugin.h \ + wallitem.h \ + simitembase.h \ + apoplastitem.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o wallbase.o wallbase.cpp + +wall.o: wall.cpp wall.h \ + wallbase.h \ + vector.h \ + sqr.h \ + cell.h \ + parameter.h \ + warning.h \ + cellbase.h \ + wallitem.h \ + simitembase.h \ + node.h \ + random.h \ + modelelement.h \ + Neighbor.h \ + apoplastitem.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o wall.o wall.cpp -clean: - make -f Makefile.libplugin clean - make -f Makefile.VirtualLeaf clean - make -C build_models clean +wallitem.o: wallitem.cpp canvas.h \ + simitembase.h \ + mainbase.h \ + mesh.h \ + cell.h \ + vector.h \ + sqr.h \ + parameter.h \ + wall.h \ + wallbase.h \ + warning.h \ + cellbase.h \ + node.h \ + random.h \ + modelelement.h \ + Neighbor.h \ + simplugin.h \ + cellitem.h \ + infobar.h \ + nodeitem.h \ + data_plot.h \ + curvecolors.h \ + wallitem.h \ + transporterdialog.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o wallitem.o wallitem.cpp + +warning.o: warning.cpp warning.h \ + canvas.h \ + simitembase.h \ + mainbase.h \ + mesh.h \ + cell.h \ + vector.h \ + sqr.h \ + parameter.h \ + wall.h \ + wallbase.h \ + cellbase.h \ + node.h \ + random.h \ + modelelement.h \ + Neighbor.h \ + simplugin.h \ + cellitem.h \ + infobar.h \ + nodeitem.h \ + data_plot.h \ + curvecolors.h \ + UniqueMessage.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o warning.o warning.cpp + +xmlwritecode.o: xmlwritecode.cpp xmlwrite.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o xmlwritecode.o xmlwritecode.cpp -#finis +xmlwrite.o: xmlwrite.cpp mesh.h \ + cell.h \ + vector.h \ + sqr.h \ + parameter.h \ + wall.h \ + wallbase.h \ + warning.h \ + cellbase.h \ + node.h \ + random.h \ + modelelement.h \ + Neighbor.h \ + simplugin.h \ + xmlwrite.h \ + nodeset.h \ + output.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o xmlwrite.o xmlwrite.cpp + +VirtualLeaf.o: VirtualLeaf.cpp mesh.h \ + cell.h \ + vector.h \ + sqr.h \ + parameter.h \ + wall.h \ + wallbase.h \ + warning.h \ + cellbase.h \ + node.h \ + random.h \ + modelelement.h \ + Neighbor.h \ + simplugin.h \ + pi.h \ + cellitem.h \ + simitembase.h \ + canvas.h \ + mainbase.h \ + infobar.h \ + nodeitem.h \ + data_plot.h \ + curvecolors.h \ + output.h \ + modelcatalogue.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o VirtualLeaf.o VirtualLeaf.cpp + +moc_canvas.o: moc_canvas.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_canvas.o moc_canvas.cpp + +moc_cellbase.o: moc_cellbase.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_cellbase.o moc_cellbase.cpp + +moc_cell.o: moc_cell.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_cell.o moc_cell.cpp + +moc_infobar.o: moc_infobar.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_infobar.o moc_infobar.cpp + +moc_modelcatalogue.o: moc_modelcatalogue.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_modelcatalogue.o moc_modelcatalogue.cpp + +moc_OptionFileDialog.o: moc_OptionFileDialog.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_OptionFileDialog.o moc_OptionFileDialog.cpp + +moc_pardialog.o: moc_pardialog.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_pardialog.o moc_pardialog.cpp + +moc_transporterdialog.o: moc_transporterdialog.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_transporterdialog.o moc_transporterdialog.cpp + +moc_UniqueMessage.o: moc_UniqueMessage.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_UniqueMessage.o moc_UniqueMessage.cpp + +####### Install + +install: FORCE + +uninstall: FORCE + +FORCE: + diff --git a/src/TutorialCode/Tutorial1A/mymodel.cpp b/src/TutorialCode/Tutorial1A/mymodel.cpp new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1A/mymodel.cpp @@ -0,0 +1,70 @@ +/* + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Virtual Leaf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Virtual Leaf. If not, see . + * + * Copyright 2010 Roeland Merks. + * + */ + +#include +#include + +#include "simplugin.h" + +#include "parameter.h" + +#include "wallbase.h" +#include "cellbase.h" +#include "mymodel.h" + +static const std::string _module_id("$Id$"); + +QString MyModel::ModelID(void) { + // specify the name of your model here + return QString( "Cell growth" ); +} + +// return the number of chemicals your model uses +int MyModel::NChem(void) { return 0; } + +// To be executed after cell division +void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { + // rules to be executed after cell division go here + // (e.g., cell differentiation rules) +} + +void MyModel::SetCellColor(CellBase *c, QColor *color) { + // add cell coloring rules here + +} + +void MyModel::CellHouseKeeping(CellBase *c) { + // add cell behavioral rules here + c->EnlargeTargetArea(par->cell_expansion_rate); +} + +void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { + // add biochemical transport rules here +} +void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) { + // add biochemical networks for reactions occuring at walls here +} +void MyModel::CellDynamics(CellBase *c, double *dchem) { + // add biochemical networks for intracellular reactions here +} + + +Q_EXPORT_PLUGIN2(mymodel, MyModel) diff --git a/src/TutorialCode/Tutorial1A/mymodel.h b/src/TutorialCode/Tutorial1A/mymodel.h new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1A/mymodel.h @@ -0,0 +1,60 @@ +/* + * $Id$ + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Virtual Leaf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Virtual Leaf. If not, see . + * + * Copyright 2010 Roeland Merks. + * + */ + + +#include +#include +#include +#include "simplugin.h" + + +class MyModel : public QObject, SimPluginInterface { + Q_OBJECT + Q_INTERFACES(SimPluginInterface); + +public: + virtual QString ModelID(void); + + // Executed after the cellular mechanics steps have equillibrized + virtual void CellHouseKeeping (CellBase *c); + // Differential equations describing transport of chemicals from cell to cell + virtual void CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2); + + // Differential equations describing chemical reactions taking place at or near the cell walls + // (e.g. PIN accumulation) + virtual void WallDynamics(Wall *w, double *dw1, double *dw2); + + // Differential equations describing chemical reactions inside the cells + virtual void CellDynamics(CellBase *c, double *dchem); + + // to be executed after a cell division + virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2); + + // to be executed for coloring a cell + virtual void SetCellColor(CellBase *c, QColor *color); + // return number of chemicals + virtual int NChem(void); +}; + + + + diff --git a/src/TutorialCode/Tutorial1A/mymodel.pro b/src/TutorialCode/Tutorial1A/mymodel.pro new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1A/mymodel.pro @@ -0,0 +1,61 @@ +# +# $Id$ +# +# This file is part of the Virtual Leaf. +# +# The Virtual Leaf is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# The Virtual Leaf is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with the Virtual Leaf. If not, see . +# +# Copyright 2010 Roeland Merks. +# + + +TARGET = mymodel +VLEAFHOME = ../../.. + +CONFIG += release +CONFIG -= debug +CONFIG += plugin + +BINDIR = $${VLEAFHOME}/bin +LIBDIR = $${VLEAFHOME}/lib +INCDIR = $${VLEAFHOME}/src +DEFINES = QTGRAPHICS # VLEAFPLUGIN +DESTDIR = $${BINDIR}/models +HEADERS = $${TARGET}.h +INCLUDEPATH += $${INCDIR} + +QMAKE_CXXFLAGS += -fexceptions #-I$${INCDIR} +QMAKE_CXXFLAGS_DEBUG += -g3 +QMAKE_CXXFLAGS_DEBUG += -DQDEBUG +QT += qt3support +SOURCES = $${TARGET}.cpp +TEMPLATE = lib + +unix { + LIBS += -L$${LIBDIR} -lvleaf + QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2 + QMAKE_LFLAGS += -fPIC +} + +win32 { + LIBXML2DIR = C:\libxml2 + LIBICONVDIR = C:\libiconv + LIBZDIR = C:\libz + LIBS += -L$${LIBDIR} -lvleaf + QMAKE_CXXFLAGS += -DLIBXML_STATIC + QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include + +} + +# finish diff --git a/src/TutorialCode/Tutorial1B/mymodel.cpp b/src/TutorialCode/Tutorial1B/mymodel.cpp new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1B/mymodel.cpp @@ -0,0 +1,73 @@ +/* + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Virtual Leaf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Virtual Leaf. If not, see . + * + * Copyright 2010 Roeland Merks. + * + */ + +#include +#include + +#include "simplugin.h" + +#include "parameter.h" + +#include "wallbase.h" +#include "cellbase.h" +#include "mymodel.h" + +static const std::string _module_id("$Id$"); + +QString MyModel::ModelID(void) { + // specify the name of your model here + return QString( "Cell growth and cell division" ); +} + +// return the number of chemicals your model uses +int MyModel::NChem(void) { return 0; } + +// To be executed after cell division +void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { + // rules to be executed after cell division go here + // (e.g., cell differentiation rules) +} + +void MyModel::SetCellColor(CellBase *c, QColor *color) { + // add cell coloring rules here + +} + +void MyModel::CellHouseKeeping(CellBase *c) { + // add cell behavioral rules here + c->EnlargeTargetArea(par->cell_expansion_rate); + if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) { + c->Divide(); + } +} + +void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { + // add biochemical transport rules here +} +void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) { + // add biochemical networks for reactions occuring at walls here +} +void MyModel::CellDynamics(CellBase *c, double *dchem) { + // add biochemical networks for intracellular reactions here +} + + +Q_EXPORT_PLUGIN2(mymodel, MyModel) diff --git a/src/TutorialCode/Tutorial1B/mymodel.h b/src/TutorialCode/Tutorial1B/mymodel.h new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1B/mymodel.h @@ -0,0 +1,60 @@ +/* + * $Id$ + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Virtual Leaf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Virtual Leaf. If not, see . + * + * Copyright 2010 Roeland Merks. + * + */ + + +#include +#include +#include +#include "simplugin.h" + + +class MyModel : public QObject, SimPluginInterface { + Q_OBJECT + Q_INTERFACES(SimPluginInterface); + +public: + virtual QString ModelID(void); + + // Executed after the cellular mechanics steps have equillibrized + virtual void CellHouseKeeping (CellBase *c); + // Differential equations describing transport of chemicals from cell to cell + virtual void CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2); + + // Differential equations describing chemical reactions taking place at or near the cell walls + // (e.g. PIN accumulation) + virtual void WallDynamics(Wall *w, double *dw1, double *dw2); + + // Differential equations describing chemical reactions inside the cells + virtual void CellDynamics(CellBase *c, double *dchem); + + // to be executed after a cell division + virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2); + + // to be executed for coloring a cell + virtual void SetCellColor(CellBase *c, QColor *color); + // return number of chemicals + virtual int NChem(void); +}; + + + + diff --git a/src/TutorialCode/Tutorial1B/mymodel.pro b/src/TutorialCode/Tutorial1B/mymodel.pro new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1B/mymodel.pro @@ -0,0 +1,61 @@ +# +# $Id$ +# +# This file is part of the Virtual Leaf. +# +# The Virtual Leaf is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# The Virtual Leaf is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with the Virtual Leaf. If not, see . +# +# Copyright 2010 Roeland Merks. +# + + +TARGET = mymodel +VLEAFHOME = ../../.. + +CONFIG += release +CONFIG -= debug +CONFIG += plugin + +BINDIR = $${VLEAFHOME}/bin +LIBDIR = $${VLEAFHOME}/lib +INCDIR = $${VLEAFHOME}/src +DEFINES = QTGRAPHICS # VLEAFPLUGIN +DESTDIR = $${BINDIR}/models +HEADERS = $${TARGET}.h +INCLUDEPATH += $${INCDIR} + +QMAKE_CXXFLAGS += -fexceptions #-I$${INCDIR} +QMAKE_CXXFLAGS_DEBUG += -g3 +QMAKE_CXXFLAGS_DEBUG += -DQDEBUG +QT += qt3support +SOURCES = $${TARGET}.cpp +TEMPLATE = lib + +unix { + LIBS += -L$${LIBDIR} -lvleaf + QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2 + QMAKE_LFLAGS += -fPIC +} + +win32 { + LIBXML2DIR = C:\libxml2 + LIBICONVDIR = C:\libiconv + LIBZDIR = C:\libz + LIBS += -L$${LIBDIR} -lvleaf + QMAKE_CXXFLAGS += -DLIBXML_STATIC + QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include + +} + +# finish diff --git a/src/TutorialCode/Tutorial1C/mymodel.cpp b/src/TutorialCode/Tutorial1C/mymodel.cpp new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1C/mymodel.cpp @@ -0,0 +1,72 @@ +/* + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Virtual Leaf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Virtual Leaf. If not, see . + * + * Copyright 2010 Roeland Merks. + * + */ + +#include +#include + +#include "simplugin.h" + +#include "parameter.h" + +#include "wallbase.h" +#include "cellbase.h" +#include "mymodel.h" + +static const std::string _module_id("$Id$"); + +QString MyModel::ModelID(void) { + // specify the name of your model here + return QString( "Cell growth and cell division" ); +} + +// return the number of chemicals your model uses +int MyModel::NChem(void) { return 0; } + +// To be executed after cell division +void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { + // rules to be executed after cell division go here + // (e.g., cell differentiation rules) +} + +void MyModel::SetCellColor(CellBase *c, QColor *color) { + // add cell coloring rules here +} + +void MyModel::CellHouseKeeping(CellBase *c) { + // add cell behavioral rules here + c->EnlargeTargetArea(par->cell_expansion_rate); + if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) { + c->DivideOverAxis(Vector(1,0,0)); + } +} + +void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { + // add biochemical transport rules here +} +void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) { + // add biochemical networks for reactions occuring at walls here +} +void MyModel::CellDynamics(CellBase *c, double *dchem) { + // add biochemical networks for intracellular reactions here +} + + +Q_EXPORT_PLUGIN2(mymodel, MyModel) diff --git a/src/TutorialCode/Tutorial1C/mymodel.h b/src/TutorialCode/Tutorial1C/mymodel.h new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1C/mymodel.h @@ -0,0 +1,60 @@ +/* + * $Id$ + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Virtual Leaf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Virtual Leaf. If not, see . + * + * Copyright 2010 Roeland Merks. + * + */ + + +#include +#include +#include +#include "simplugin.h" + + +class MyModel : public QObject, SimPluginInterface { + Q_OBJECT + Q_INTERFACES(SimPluginInterface); + +public: + virtual QString ModelID(void); + + // Executed after the cellular mechanics steps have equillibrized + virtual void CellHouseKeeping (CellBase *c); + // Differential equations describing transport of chemicals from cell to cell + virtual void CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2); + + // Differential equations describing chemical reactions taking place at or near the cell walls + // (e.g. PIN accumulation) + virtual void WallDynamics(Wall *w, double *dw1, double *dw2); + + // Differential equations describing chemical reactions inside the cells + virtual void CellDynamics(CellBase *c, double *dchem); + + // to be executed after a cell division + virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2); + + // to be executed for coloring a cell + virtual void SetCellColor(CellBase *c, QColor *color); + // return number of chemicals + virtual int NChem(void); +}; + + + + diff --git a/src/TutorialCode/Tutorial1C/mymodel.pro b/src/TutorialCode/Tutorial1C/mymodel.pro new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1C/mymodel.pro @@ -0,0 +1,61 @@ +# +# $Id$ +# +# This file is part of the Virtual Leaf. +# +# The Virtual Leaf is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# The Virtual Leaf is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with the Virtual Leaf. If not, see . +# +# Copyright 2010 Roeland Merks. +# + + +TARGET = mymodel +VLEAFHOME = ../../.. + +CONFIG += release +CONFIG -= debug +CONFIG += plugin + +BINDIR = $${VLEAFHOME}/bin +LIBDIR = $${VLEAFHOME}/lib +INCDIR = $${VLEAFHOME}/src +DEFINES = QTGRAPHICS # VLEAFPLUGIN +DESTDIR = $${BINDIR}/models +HEADERS = $${TARGET}.h +INCLUDEPATH += $${INCDIR} + +QMAKE_CXXFLAGS += -fexceptions #-I$${INCDIR} +QMAKE_CXXFLAGS_DEBUG += -g3 +QMAKE_CXXFLAGS_DEBUG += -DQDEBUG +QT += qt3support +SOURCES = $${TARGET}.cpp +TEMPLATE = lib + +unix { + LIBS += -L$${LIBDIR} -lvleaf + QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2 + QMAKE_LFLAGS += -fPIC +} + +win32 { + LIBXML2DIR = C:\libxml2 + LIBICONVDIR = C:\libiconv + LIBZDIR = C:\libz + LIBS += -L$${LIBDIR} -lvleaf + QMAKE_CXXFLAGS += -DLIBXML_STATIC + QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include + +} + +# finish diff --git a/src/TutorialCode/Tutorial1D/mymodel.cpp b/src/TutorialCode/Tutorial1D/mymodel.cpp new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1D/mymodel.cpp @@ -0,0 +1,75 @@ +/* + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Virtual Leaf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Virtual Leaf. If not, see . + * + * Copyright 2010 Roeland Merks. + * + */ + +#include +#include + +#include "simplugin.h" + +#include "parameter.h" + +#include "wallbase.h" +#include "cellbase.h" +#include "mymodel.h" + +static const std::string _module_id("$Id$"); + +QString MyModel::ModelID(void) { + // specify the name of your model here + return QString( "Growth, division, coloring" ); +} + +// return the number of chemicals your model uses +int MyModel::NChem(void) { return 0; } + +// To be executed after cell division +void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { + // rules to be executed after cell division go here + // (e.g., cell differentiation rules) +} + +void MyModel::SetCellColor(CellBase *c, QColor *color) { + // add cell coloring rules here + if (c->Area()/c->BaseArea()>1.8) { color->setNamedColor("blue"); } + else { color->setNamedColor("green"); } + +} + +void MyModel::CellHouseKeeping(CellBase *c) { + // add cell behavioral rules here + c->EnlargeTargetArea(par->cell_expansion_rate); + if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) { + c->Divide(); + } +} + +void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { + // add biochemical transport rules here +} +void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) { + // add biochemical networks for reactions occuring at walls here +} +void MyModel::CellDynamics(CellBase *c, double *dchem) { + // add biochemical networks for intracellular reactions here +} + + +Q_EXPORT_PLUGIN2(mymodel, MyModel) diff --git a/src/TutorialCode/Tutorial1D/mymodel.h b/src/TutorialCode/Tutorial1D/mymodel.h new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1D/mymodel.h @@ -0,0 +1,60 @@ +/* + * $Id$ + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Virtual Leaf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Virtual Leaf. If not, see . + * + * Copyright 2010 Roeland Merks. + * + */ + + +#include +#include +#include +#include "simplugin.h" + + +class MyModel : public QObject, SimPluginInterface { + Q_OBJECT + Q_INTERFACES(SimPluginInterface); + +public: + virtual QString ModelID(void); + + // Executed after the cellular mechanics steps have equillibrized + virtual void CellHouseKeeping (CellBase *c); + // Differential equations describing transport of chemicals from cell to cell + virtual void CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2); + + // Differential equations describing chemical reactions taking place at or near the cell walls + // (e.g. PIN accumulation) + virtual void WallDynamics(Wall *w, double *dw1, double *dw2); + + // Differential equations describing chemical reactions inside the cells + virtual void CellDynamics(CellBase *c, double *dchem); + + // to be executed after a cell division + virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2); + + // to be executed for coloring a cell + virtual void SetCellColor(CellBase *c, QColor *color); + // return number of chemicals + virtual int NChem(void); +}; + + + + diff --git a/src/TutorialCode/Tutorial1D/mymodel.pro b/src/TutorialCode/Tutorial1D/mymodel.pro new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1D/mymodel.pro @@ -0,0 +1,61 @@ +# +# $Id$ +# +# This file is part of the Virtual Leaf. +# +# The Virtual Leaf is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# The Virtual Leaf is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with the Virtual Leaf. If not, see . +# +# Copyright 2010 Roeland Merks. +# + + +TARGET = mymodel +VLEAFHOME = ../../.. + +CONFIG += release +CONFIG -= debug +CONFIG += plugin + +BINDIR = $${VLEAFHOME}/bin +LIBDIR = $${VLEAFHOME}/lib +INCDIR = $${VLEAFHOME}/src +DEFINES = QTGRAPHICS # VLEAFPLUGIN +DESTDIR = $${BINDIR}/models +HEADERS = $${TARGET}.h +INCLUDEPATH += $${INCDIR} + +QMAKE_CXXFLAGS += -fexceptions #-I$${INCDIR} +QMAKE_CXXFLAGS_DEBUG += -g3 +QMAKE_CXXFLAGS_DEBUG += -DQDEBUG +QT += qt3support +SOURCES = $${TARGET}.cpp +TEMPLATE = lib + +unix { + LIBS += -L$${LIBDIR} -lvleaf + QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2 + QMAKE_LFLAGS += -fPIC +} + +win32 { + LIBXML2DIR = C:\libxml2 + LIBICONVDIR = C:\libiconv + LIBZDIR = C:\libz + LIBS += -L$${LIBDIR} -lvleaf + QMAKE_CXXFLAGS += -DLIBXML_STATIC + QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include + +} + +# finish diff --git a/src/TutorialCode/Tutorial2/mymodel.cpp b/src/TutorialCode/Tutorial2/mymodel.cpp --- a/src/TutorialCode/Tutorial2/mymodel.cpp +++ b/src/TutorialCode/Tutorial2/mymodel.cpp @@ -34,26 +34,66 @@ static const std::string _module_id("$Id QString MyModel::ModelID(void) { // specify the name of your model here - return QString( "Cell growth and cell division" ); + return QString( "Growth hormones" ); } // return the number of chemicals your model uses -int MyModel::NChem(void) { return 0; } +int MyModel::NChem(void) { return 1; } // To be executed after cell division void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { // rules to be executed after cell division go here // (e.g., cell differentiation rules) + + // set one cell to source after first division + if (CellBase::NCells()==2) { + daughter1->SetCellType(1); + daughter2->SetCellType(0); + } + + // if a source cells has divided, one of the daughters becomes the new source + if (daughter1->CellType()==1) { + + // if both cells are at the tissue perimeter, choose at random + if (daughter1->AtBoundaryP() && daughter2->AtBoundaryP()) { + + if (qrand()%2){ + daughter1->SetCellType(1); + daughter2->SetCellType(0); + } else { + daughter1->SetCellType(0); + daughter2->SetCellType(1); + } + } else { + // otherwise choose the one that is still at the perimeter + if (daughter1->AtBoundaryP()) { + daughter1->SetCellType(1); + daughter2->SetCellType(0); + } else { + daughter1->SetCellType(0); + daughter2->SetCellType(1); + } + } + } + } void MyModel::SetCellColor(CellBase *c, QColor *color) { // add cell coloring rules here - + + // white: high concentration of growth hormone, black low concentration + double val = 1.-c->Chemical(0)/(1.+c->Chemical(0)); + color->setRgbF(val, val, val); } void MyModel::CellHouseKeeping(CellBase *c) { // add cell behavioral rules here - c->EnlargeTargetArea(par->cell_expansion_rate); + if (CellBase::NCells()==1) + // first cell expands unconditionally + c->EnlargeTargetArea(par->cell_expansion_rate); + else + c->EnlargeTargetArea(c->Chemical(0)*par->cell_expansion_rate); + if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) { c->Divide(); } @@ -61,12 +101,19 @@ void MyModel::CellHouseKeeping(CellBase void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { // add biochemical transport rules here + double phi = w->Length() * par->D[0] * ( w->C2()->Chemical(0) - w->C1()->Chemical(0) ); + dchem_c1[0]+=phi; + dchem_c2[0]-=phi; } + void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) { // add biochemical networks for reactions occuring at walls here } void MyModel::CellDynamics(CellBase *c, double *dchem) { // add biochemical networks for intracellular reactions here + if (c->CellType()==1) { + dchem[0] = par->leaf_tip_source; + } } diff --git a/src/TutorialCode/Tutorial3/mymodel.cpp b/src/TutorialCode/Tutorial3/mymodel.cpp --- a/src/TutorialCode/Tutorial3/mymodel.cpp +++ b/src/TutorialCode/Tutorial3/mymodel.cpp @@ -34,38 +34,99 @@ static const std::string _module_id("$Id QString MyModel::ModelID(void) { // specify the name of your model here - return QString( "Cell growth and cell division" ); + return QString( "Growth hormones" ); } // return the number of chemicals your model uses -int MyModel::NChem(void) { return 0; } +int MyModel::NChem(void) { return 2; } // To be executed after cell division void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { // rules to be executed after cell division go here // (e.g., cell differentiation rules) + + // set one cell to source after first division + if (CellBase::NCells()==2) { + daughter1->SetCellType(1); + daughter2->SetCellType(0); + } + + // if a source cells has divided, one of the daughters becomes the new source + if (daughter1->CellType()==1) { + + // if both cells are at the tissue perimeter, choose at random + if (daughter1->AtBoundaryP() && daughter2->AtBoundaryP()) { + + if (qrand()%2){ + daughter1->SetCellType(1); + daughter2->SetCellType(0); + } else { + daughter1->SetCellType(0); + daughter2->SetCellType(1); + } + } else { + // otherwise choose the one that is still at the perimeter + if (daughter1->AtBoundaryP()) { + daughter1->SetCellType(1); + daughter2->SetCellType(0); + } else { + daughter1->SetCellType(0); + daughter2->SetCellType(1); + } + } + } + } void MyModel::SetCellColor(CellBase *c, QColor *color) { // add cell coloring rules here + + // white: high concentration of growth hormone, black low concentration + double val = 1.-c->Chemical(0)/(1.+c->Chemical(0)); + color->setRgbF(val, val, val); } void MyModel::CellHouseKeeping(CellBase *c) { // add cell behavioral rules here - c->EnlargeTargetArea(par->cell_expansion_rate); + if (CellBase::NCells()==1) + // first cell expands unconditionally + c->EnlargeTargetArea(par->cell_expansion_rate); + else + c->EnlargeTargetArea(c->Chemical(0)*par->cell_expansion_rate); + if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) { - c->DivideOverAxis(Vector(1,0,0)); + c->Divide(); } } void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { // add biochemical transport rules here + double phi = w->Length() * par->D[0] * ( w->C2()->Chemical(0) - w->C1()->Chemical(0) ); + dchem_c1[0]+=phi; + dchem_c2[0]-=phi; + + // directed transport + // efflux from cell 1 to cell 2 + double trans12 = ( par->transport * w->Transporters1(1) * + w->C1()->Chemical(0) / (par->ka + w->C1()->Chemical(0)) ); + + // efflux from cell 2 to cell 1 + double trans21 = ( par->transport * w->Transporters2(1) * + w->C2()->Chemical(0) / (par->ka + w->C2()->Chemical(0)) ); + + dchem_c1[0] += trans21 - trans12; + dchem_c2[0] += trans12 - trans21; + } + void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) { // add biochemical networks for reactions occuring at walls here } void MyModel::CellDynamics(CellBase *c, double *dchem) { // add biochemical networks for intracellular reactions here + if (c->CellType()==1) { + dchem[0] = par->leaf_tip_source; + } } diff --git a/src/TutorialCode/Tutorial3/tutorial3_init.xml b/src/TutorialCode/Tutorial3/tutorial3_init.xml new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial3/tutorial3_init.xml @@ -0,0 +1,20702 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #include <fstream> +#include <sstream> +#include <cstring> +#include <functional> +#include <getopt.h> +#include <cerrno> +#include "mesh.h" +#include "parameter.h" +#include "random.h" +#include "pi.h" +#include "cellitem.h" +#include "canvas.h" +#include "cell.h" +#include "output.h" +#include <qwidget.h> +#include <q3process.h> +#include <qapplication.h> +#include <QDesktopWidget> +#include <QGraphicsScene> +#include <QMessageBox> +//Added by qt3to4: +#include <QMouseEvent> + +#include <unistd.h> +#include <q3textstream.h> + + +#ifdef HAVE_QWT +#include "data_plot.h" +#endif +#include <QPalette> +#include <QBrush> +#include <QToolTip> +#include "simplugin.h" +#include "testplugin.h" + +/* #define _xstr_(s) _str_(s) +#define _str_(s) #s +#include _xstr_(REACTIONS_HEADER) +*/ +extern Parameter par; + +MainBase *main_window = 0; +double auxin_account = 0.; + + + +TestPlugin *plugin = new TestPlugin(); + +#ifdef XFIGGRAPHICS +#define TIMESTEP double Graphics::TimeStep(void) +#endif + +class PrintNode { +public: + void operator() (const Node &n) const + { + cerr << n.Index() << ": " << n << endl; + } +}; + + +class EdgeSource { + +public: + void operator() (Cell &c) { + + if (c.AtBoundaryP()) { + cerr << "Cell " << c.Index() << " is a source cell.\n"; + c.SetSource(0,par.source); + } else { + cerr << "Cell " << c.Index() << " is _not_ a source cell.\n"; + } + } + +}; + + + +class CellInfo { +public: + void operator() (Cell &c,std::ostream &os) const { + os << "Cell " << c.index << " says: " << endl; + os << "c.nodes.size() = " << c.nodes.size() << endl; + for (list<Node *>::iterator i=c.nodes.begin(); + i!=c.nodes.end(); + i++) { + cerr << (*i)->Index() << " "; + } + cerr << endl; + } +}; + +double PINSum(Cell &c) { + + return c.Chemical(1) + c.SumTransporters(1);// + c.ReduceCellAndWalls<double>( complex_PijAj ); + +} + + +class DrawCell { +public: + void operator() (Cell &c,QGraphicsScene &canvas, MainBase &m) const { + if (m.ShowBorderCellsP() || c.Boundary()==Cell::None) { + if (!m.ShowBoundaryOnlyP() && !m.HideCellsP()) + if (m.ShowToolTipsP()) { + QString info_string=QString("Cell %1, chemicals: ( %2, %3, %4, %5, %6)\n %7 of PIN1 at walls.\n Area is %8\n PIN sum is %9\n Circumference is %10\n Boundary type is %11").arg(c.Index()).arg(c.Chemical(0)).arg(c.Chemical(1)).arg(c.Chemical(2)).arg(c.Chemical(3)).arg(c.Chemical(4)).arg(c.SumTransporters(1)).arg(c.Area()).arg(PINSum(c)).arg(c.Circumference()).arg(c.BoundaryStr()); + + info_string += "\n" + c.printednodelist(); + + c.Draw(&canvas, info_string); + } else { + c.Draw(&canvas); + } + if (m.ShowCentersP()) + c.DrawCenter(&canvas); + if (m.ShowFluxesP()) + c.DrawFluxes(&canvas, par.arrowsize); + + } + + } + +}; + +Mesh mesh; +bool batch=false; + + +void MainBase::Plot(int resize_stride) { + + clear(); + + + static int count=0; + if (resize_stride) { + if ( !((++count)%resize_stride) ) { + FitLeafToCanvas(); + } + } + mesh.LoopCells(DrawCell(),canvas,*this); + + if (ShowNodeNumbersP()) + mesh.LoopNodes( bind2nd (mem_fun_ref ( &Node::DrawIndex), &canvas ) ) ; + if (ShowCellNumbersP()) + mesh.LoopCells( bind2nd (mem_fun_ref ( &Cell::DrawIndex), &canvas ) ) ; + + if (ShowCellAxesP()) + mesh.LoopCells( bind2nd (mem_fun_ref ( &Cell::DrawAxis), &canvas ) ); + + if (ShowCellStrainP()) + mesh.LoopCells( bind2nd (mem_fun_ref ( &Cell::DrawStrain), &canvas ) ); + + if (ShowWallsP()) + + mesh.LoopWalls( bind2nd( mem_fun_ref( &Wall::Draw ), &canvas ) ); + + if (ShowApoplastsP()) + mesh.LoopWalls( bind2nd( mem_fun_ref( &Wall::DrawApoplast ), &canvas ) ); + + if (ShowMeshP()) + mesh.DrawNodes(&canvas); + + if (ShowBoundaryOnlyP()) + mesh.DrawBoundary(&canvas); + + + if ( ( batch || MovieFramesP() )) { + + static int frame = 0; + // frame numbers are sequential for the most frequently written file type. + // for the less frequently written file type they match the other type + if (!(count%par.storage_stride) ) { + + stringstream fname; + fname << par.datadir << "/leaf."; + fname.fill('0'); + fname.width(6); + + /* + fname << frame << ".pdf"; + if (par.storage_stride <= par.xml_storage_stride) { + frame++; + } + + // Write high-res JPG snapshot every plot step + Save(fname.str().c_str(), "PDF"); + */ + + fname << frame << ".jpg"; + if (par.storage_stride <= par.xml_storage_stride) { + frame++; + } + + // Write high-res JPG snapshot every plot step + Save(fname.str().c_str(), "JPEG",1024,768); + + } + + if (!(count%par.xml_storage_stride)) { + stringstream fname; + fname << par.datadir << "/leaf."; + fname.fill('0'); + fname.width(6); + fname << frame << ".xml"; + + if (par.xml_storage_stride < par.storage_stride) { + frame++; + } + // Write XML file every ten plot steps + mesh.XMLSave(fname.str().c_str(), XMLSettingsTree()); + } + + } +} + + +void Cell::Flux(double *flux, double *D) { + + + // loop over cell edges + + for (int c=0;c<Cell::nchem;c++) flux[c]=0.; + + for (list<Wall *>::iterator i=walls.begin(); + i!=walls.end(); + i++) { + + + // leaf cannot take up chemicals from environment ("no flux boundary") + if ((*i)->c2->BoundaryPolP()) continue; + + + // flux depends on edge length and concentration difference + for (int c=0;c<Cell::nchem;c++) { + double phi = (*i)->length * ( D[c] ) * ( (*i)->c2->chem[c] - chem[c] ); + + if ((*i)->c1!=this) { + cerr << "Warning, bad cells boundary: " << (*i)->c1->index << ", " << index << endl; + } + + flux[c] += phi; + } + } + +} + +INIT { + + if (leaffile) { + xmlNode *settings; + mesh.XMLRead(leaffile, &settings); + main_window->XMLReadSettings(settings); + xmlFree(settings); + main_window->UserMessage(QString("Ready. Time is %1").arg(mesh.getTimeHours().c_str())); + + } else { + + Cell &circle=mesh.CircularCell(0,0,10,10); + + circle.SetTargetArea(circle.CalcArea()); + mesh.SetBaseArea(); + // clean up chemicals + for (int c=0; c<Cell::NChem(); c++) { + circle.SetChemical(c, 0.); + } + } +} + +TIMESTEP { + + static int i=0; + static int t=0; + static int ncells; + + if (!batch) { + UserMessage(QString("Time: %1").arg(mesh.getTimeHours().c_str()),0); + } + + ncells=mesh.NCells(); + + + double dh; + + if(DynamicCellsP()) { + dh = mesh.DisplaceNodes(); + + // Only allow for node insertion, cell division and cell growth + // if the system has equillibrized + // i.e. cell wall tension equillibrization is much faster + // than biological processes, including division, cell wall yielding + // and cell expansion + mesh.InsertNodes(); // (this amounts to cell wall yielding) + + if ( (-dh) < par.energy_threshold) { + + mesh.IncreaseCellCapacityIfNecessary(); + mesh.LoopCurrentCells(&TestPlugin::CellHouseKeeping); // this includes cell division + + // Reaction diffusion + /*CelltoCellTransport *transport_f = &TestPlugin::CelltoCellTransport; + CellReaction *cellreaction_f = new plugin->CellDynamics(); + WallReaction *wall_f = new WallDynamics();*/ + + mesh.ReactDiffuse(plugin, par.rd_dt); + + + t++; + + Plot(par.resize_stride); + + /*QVector< QPair<double, int> > angles=mesh.VertexAnglesValues(); + QString afname=QString("Angles/anglesvalues%1.dat").arg(t,6,10,QChar('0')); + ofstream af(afname.toStdString().c_str()); + */ + + /*for (QVector< QPair<qreal, int> >::const_iterator v=angles.begin(); + v!=angles.end(); + v++) { + af << v->first << " " << v->second << endl; + } + */ + } + + } else { + + /* TransportFunction *transport_f = new CelltoCellTransport(); + CellReaction *cellreaction_f = new CellDynamics(); + WallReaction *wall_f = new WallDynamics(); + + mesh.ReactDiffuse_New(transport_f, cellreaction_f, wall_f, par.rd_dt);*/ + mesh.ReactDiffuse(plugin, par.rd_dt); + + Plot(par.resize_stride); + + } + + + + + + i++; + return mesh.getTime(); + +} + + + +/* Called if a cell is clicked */ +void Cell::OnClick(QMouseEvent *e) { + +} + + + +void Wall::OnWallInsert(void) { + + +} + + + + +int main(int argc,char **argv) { + + try { + + + int c; + + + char *leaffile=0; + + + while (1) { + + //int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = { + {"batch", 0, 0, 0}, + {"leaffile", 2, 0, 0} + }; + + // short option 'p' creates trouble for non-commandline usage on MacOSX. Option -p changed to -P (capital) + static char *short_options = "bl"; + c = getopt_long (argc, argv, "bl:", + long_options, &option_index); + if (c == -1) + break; + + + if (c==0) { + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + + c = short_options[option_index]; + } + + switch (c) { + case 'b': + cerr << "Running in batch mode\n"; + batch=true; + break; + + case 'l': + leaffile=strdup(optarg); + if (!leaffile) { + throw("Out of memory"); + } + printf("Reading leaf state file '%s'\n", leaffile); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + + if (optind < argc) { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + MakeDir("Angles"); + bool useGUI = !batch; + QApplication app(argc,argv,useGUI); + + + + QPalette tooltippalette = QToolTip::palette(); + QColor transparentcolor = QColor(tooltippalette.brush(QPalette::Window).color()); + + tooltippalette.setBrush (QPalette::Window, QBrush (transparentcolor) ); + QToolTip::setPalette( tooltippalette ); + + QGraphicsScene canvas(0,0,8000,6000); + + if (useGUI) { + main_window=new Main(canvas, mesh); + if ( QApplication::desktop()->width() > ((Main *)main_window)->width() + 10 + && QApplication::desktop()->height() > ((Main *)main_window)->height() +30 ) { + + ((Main *)main_window)->show(); + ((Main *)main_window)->resize( ((Main *)main_window)->sizeHint()); + } else { + ((Main *)main_window)->showMaximized(); + } + } else { + main_window=new MainBase(canvas, mesh); + + } + + + + canvas.setSceneRect(QRectF()); + if (!batch) { + QObject::connect( qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()) ); + } + + + + main_window->Init(leaffile); + + Cell::SetMagnification(1); + Cell::setOffset(0,0); + + main_window->FitLeafToCanvas(); + + + + main_window->Plot(); + + + + if (batch) { + double t=0.; + do { + t = main_window->TimeStep(); + } while (t < par.maxt); + + } else + return app.exec(); + + + } catch (const char *message) { + if (batch) { + cerr << "Exception caught:" << endl; + cerr << message << endl; + abort(); + } else { + QString qmess=QString("Exception caught: %1").arg(message); + QMessageBox::critical(0, "Critical Error", qmess); + abort(); + } + } catch (ios_base::failure) { + stringstream error_message; + error_message << "I/O failure: " << strerror(errno); + if (batch) { + cerr << error_message.str() <<endl; + abort(); + } else { + QString qmess(error_message.str().c_str()); + QMessageBox::critical(0, "I/O Error", qmess ); + abort(); + } + } + +} + + + +// Executed after the cellular mechanics steps have equillibrized +class CellHouseKeeping { +public: + void operator() (Cell &c) const { + + c.EnlargeTargetArea(par.cell_expansion_rate); + + if (c.Area() > par.rel_cell_div_threshold * c.BaseArea() ) { + c.Divide(); + } + } +}; + +// The number of chemical species in the cels +const int Cell::nchem = 0; + +// Differential equations describing transport of chemicals from cell to cell +class CelltoCellTransport : public TransportFunction { + + public: + virtual void operator()(Wall *w, double *dchem_c1, double *dchem_c2) {} + + }; + +// Differential equations describing chemical reactions taking place at or near the cell walls +// (e.g. PIN accumulation) +class WallDynamics : public WallReaction { + public: + virtual void operator()(Wall *w, double *dw1, double *dw2) {}; + +}; + + +// Differential equations describing chemical reactions inside the cells +class CellDynamics : public CellReaction { + public: + virtual void operator()(Cell *c, double *dchem) { + + }; + +}; + +// Rules for cell coloring +void Cell::SetColor(QColor &color) { } + +// To be executed after cell division +void Cell::OnDivide(ParentInfo &parent_info, Cell &daughter) {} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/TutorialCode/Tutorial4/auxin_growth_init.xml b/src/TutorialCode/Tutorial4/auxin_growth_init.xml new file mode 100644 index 0000000000000000000000000000000000000000..1712638981c21653fb443959ec345c47f6f91968 GIT binary patch literal 6918 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 M3p}6-BadqU05YdWBme*a diff --git a/src/TutorialCode/Tutorial4/mymodel b/src/TutorialCode/Tutorial4/mymodel new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial4/mymodel @@ -0,0 +1,147 @@ +/* + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Virtual Leaf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Virtual Leaf. If not, see . + * + * Copyright 2010 Roeland Merks. + * + */ + +#include +#include +#include +#include "simplugin.h" + +#include "parameter.h" + +#include "wallbase.h" +#include "cellbase.h" +#include "mymodel.h" +#include "flux_function.h" + +static const std::string _module_id("$Id$"); + +QString MyModel::ModelID(void) { + // specify the name of your model here + return QString( "new auxin transport 2" ); +} + +// return the number of chemicals your model uses +int MyModel::NChem(void) { return 2; } + +// To be executed after cell division +void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { + + // After divisions, parent and daughter cells get a standard stock of PINs. + daughter1->SetChemical(1, par->initval[1]); + daughter2->SetChemical(1, par->initval[1]); + + +} + +void MyModel::SetCellColor(CellBase *c, QColor *color) { + // add cell coloring rules here + // Red: PIN1 + // Green: Auxin + color->setRgb(c->Chemical(1)/(1+c->Chemical(1)) * 255.,(c->Chemical(0)/(1+c->Chemical(0)) * 255.), 0); + +} + +void MyModel::CellHouseKeeping(CellBase *c) { + // add cell behavioral rules here + + c->EnlargeTargetArea(c->Chemical(0)/(1.+c->Chemical(0))*par->cell_expansion_rate); + + if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) { + c->Divide(); + } +} + +void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { + // add biochemical transport rules here + double phi = w->Length() * par->D[0] * ( w->C2()->Chemical(0) - w->C1()->Chemical(0) ); + dchem_c1[0]+=phi; + dchem_c2[0]-=phi; + + // Active fluxes (PIN1 mediated transport) + + // (Transporters measured in moles, here) + // efflux from cell 1 to cell 2 + double trans12 = ( par->transport * w->Transporters1(1) * w->C1()->Chemical(0) / (par->ka + w->C1()->Chemical(0)) ); + + // efflux from cell 2 to cell 1 + double trans21 = ( par->transport * w->Transporters2(1) * w->C2()->Chemical(0) / (par->ka + w->C2()->Chemical(0)) ); + + dchem_c1[0] += trans21 - trans12; + dchem_c2[0] += trans12 - trans21; + + // Influx at leaf "AuxinSource" (as specified in initial condition) + if (w->AuxinSource()) { + double aux_flux = par->leaf_tip_source * w->Length(); + dchem_c1[0] += aux_flux; + dchem_c2[0] += aux_flux; + } +} + +double MyModel::PINflux(CellBase *this_cell, CellBase *adjacent_cell, Wall *w) { + // PIN1 localization at wall + // Note: chemical 0 is Auxin (intracellular storage only) + // PIN1 is Chemical 1 (both in walls and intracellular storage) + //! \f$ \frac{d Pij/dt}{dt} = k_1 A_j \frac{P_i}{L_ij} - k_2 P_{ij} \f$ + // Note that Pij is measured in term of concentration (mol/L) + // Pi in terms of quantity (mol) + + // Equations as in Merks et al., Trends in Plant Science 2007 + + // calculate PIN translocation rate from cell to membrane + double adj_auxin = adjacent_cell->Chemical(0); + double receptor_level = adj_auxin * par->r / (par->kr + adj_auxin); + double pin_atwall; // pick the correct side of the Wall + + if (w->C1() == this_cell) pin_atwall = w->Transporters1(1); + else pin_atwall=w->Transporters2(1); + + // note: pin_flux is net flux from endosome to wall + double pin_flux = par->k1 * this_cell->Chemical(1) * receptor_level / ( par->km + this_cell->Chemical(1) ) - par->k2 * pin_atwall; + return pin_flux; + + +} + + +void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) { + // add biochemical networks for reactions occuring at walls here + dw1[0] = 0.; dw2[0] = 0.; // chemical 0 unused in walls + dw1[1] = PINflux(w->C1(),w->C2(),w); + dw2[1] = PINflux(w->C2(),w->C1(),w); + //static ofstream pf("pin_flux.dat"); + //pf << dw1[1] << " " << dw2[1] << " " << w->C1()->Chemical(1) << " " << w->C2()->Chemical(1) << endl; + +} + +void MyModel::CellDynamics(CellBase *c, double *dchem) { + // add biochemical networks for intracellular reactions here + + // sum all incoming fluxes of PINs + dchem[1] = - SumFluxFromWalls( c, MyModel::PINflux ); + + // auxin degradation + dchem[0] = - par->aux_breakdown * c->Chemical(0); + + +} + + +Q_EXPORT_PLUGIN2(mymodel, MyModel) diff --git a/src/TutorialCode/Tutorial4/mymodel.cpp b/src/TutorialCode/Tutorial4/mymodel.cpp --- a/src/TutorialCode/Tutorial4/mymodel.cpp +++ b/src/TutorialCode/Tutorial4/mymodel.cpp @@ -21,7 +21,7 @@ #include #include - +#include #include "simplugin.h" #include "parameter.h" @@ -29,33 +29,41 @@ #include "wallbase.h" #include "cellbase.h" #include "mymodel.h" +#include "flux_function.h" static const std::string _module_id("$Id$"); QString MyModel::ModelID(void) { // specify the name of your model here - return QString( "Growth, division, coloring" ); + return QString( "new auxin transport 2" ); } // return the number of chemicals your model uses -int MyModel::NChem(void) { return 0; } +int MyModel::NChem(void) { return 2; } // To be executed after cell division void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { - // rules to be executed after cell division go here - // (e.g., cell differentiation rules) + + // After divisions, parent and daughter cells get a standard stock of PINs. + daughter1->SetChemical(1, par->initval[1]); + daughter2->SetChemical(1, par->initval[1]); + + } void MyModel::SetCellColor(CellBase *c, QColor *color) { // add cell coloring rules here - if (c->Area()/c->BaseArea()>1.8) { color->setNamedColor("blue"); } - else { color->setNamedColor("green"); } - + // Red: PIN1 + // Green: Auxin + color->setRgb(c->Chemical(1)/(1+c->Chemical(1)) * 255.,(c->Chemical(0)/(1+c->Chemical(0)) * 255.), 0); + } void MyModel::CellHouseKeeping(CellBase *c) { // add cell behavioral rules here - c->EnlargeTargetArea(par->cell_expansion_rate); + + c->EnlargeTargetArea(c->Chemical(0)/(1.+c->Chemical(0))*par->cell_expansion_rate); + if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) { c->Divide(); } @@ -63,12 +71,74 @@ void MyModel::CellHouseKeeping(CellBase void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { // add biochemical transport rules here + double phi = w->Length() * par->D[0] * ( w->C2()->Chemical(0) - w->C1()->Chemical(0) ); + dchem_c1[0]+=phi; + dchem_c2[0]-=phi; + + // Active fluxes (PIN1 mediated transport) + + // (Transporters measured in moles, here) + // efflux from cell 1 to cell 2 + double trans12 = ( par->transport * w->Transporters1(1) * w->C1()->Chemical(0) / (par->ka + w->C1()->Chemical(0)) ); + + // efflux from cell 2 to cell 1 + double trans21 = ( par->transport * w->Transporters2(1) * w->C2()->Chemical(0) / (par->ka + w->C2()->Chemical(0)) ); + + dchem_c1[0] += trans21 - trans12; + dchem_c2[0] += trans12 - trans21; + + // Influx at leaf "AuxinSource" (as specified in initial condition) + if (w->AuxinSource()) { + double aux_flux = par->leaf_tip_source * w->Length(); + dchem_c1[0] += aux_flux; + dchem_c2[0] += aux_flux; + } } + +double MyModel::PINflux(CellBase *this_cell, CellBase *adjacent_cell, Wall *w) { + // PIN1 localization at wall + // Note: chemical 0 is Auxin (intracellular storage only) + // PIN1 is Chemical 1 (both in walls and intracellular storage) + //! \f$ \frac{d Pij/dt}{dt} = k_1 A_j \frac{P_i}{L_ij} - k_2 P_{ij} \f$ + // Note that Pij is measured in term of concentration (mol/L) + // Pi in terms of quantity (mol) + + // Equations as in Merks et al., Trends in Plant Science 2007 + + // calculate PIN translocation rate from cell to membrane + double adj_auxin = adjacent_cell->Chemical(0); + double receptor_level = adj_auxin * par->r / (par->kr + adj_auxin); + double pin_atwall; // pick the correct side of the Wall + + if (w->C1() == this_cell) pin_atwall = w->Transporters1(1); + else pin_atwall=w->Transporters2(1); + + // note: pin_flux is net flux from endosome to wall + double pin_flux = par->k1 * this_cell->Chemical(1) * receptor_level / ( par->km + this_cell->Chemical(1) ) - par->k2 * pin_atwall; + return pin_flux; + + +} + + void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) { // add biochemical networks for reactions occuring at walls here + dw1[0] = 0.; dw2[0] = 0.; // chemical 0 unused in walls + dw1[1] = PINflux(w->C1(),w->C2(),w); + dw2[1] = PINflux(w->C2(),w->C1(),w); + //static ofstream pf("pin_flux.dat"); + //pf << dw1[1] << " " << dw2[1] << " " << w->C1()->Chemical(1) << " " << w->C2()->Chemical(1) << endl; + } + void MyModel::CellDynamics(CellBase *c, double *dchem) { - // add biochemical networks for intracellular reactions here + // add biochemical networks for intracellular reactions here + + // sum all incoming fluxes of PINs + dchem[1] = - SumFluxFromWalls( c, MyModel::PINflux ); + + + } diff --git a/src/TutorialCode/Tutorial4/mymodel.h b/src/TutorialCode/Tutorial4/mymodel.h --- a/src/TutorialCode/Tutorial4/mymodel.h +++ b/src/TutorialCode/Tutorial4/mymodel.h @@ -53,6 +53,8 @@ public: virtual void SetCellColor(CellBase *c, QColor *color); // return number of chemicals virtual int NChem(void); + + virtual double PINflux(CellBase *this_cell, CellBase *adjacent_cell, Wall *w); }; diff --git a/src/TutorialCode/Tutorial4/tutorial4_init.xml b/src/TutorialCode/Tutorial4/tutorial4_init.xml new file mode 100644 index 0000000000000000000000000000000000000000..b67595ecfbd63256f35e29a36bf773def8c31133 GIT binary patch literal 54441 zc$@$(K+(S+iwFP!000001MIzPlN`r!Hu@R(6(cxkEl8kI_X{XkL6ek3AB&_!T5^Q# z*cj{%fVK9fy#VCV%m02dtE;MKcAi;`mBKhQ=anr8=;^7cuFlHJ%ac$3;+H?1ozC7a zuC7lm&R;yzgL*VuoF82rpPavb@#x>a|JBp<=$HTW@E50x`K#Ia{A}^!(X)TMrrV!g zT`W$Y{o!BfI(_NcANY^!tD|S%-`-qYoy<=^zc^m>f4FBi?Qe%C=O;G<{ph3F@%)B{ z`|ZW~>|burXR|od>A6bJeVQ4iX&%=nXE!JOi|WxoJ)F&caXG)D3EV8M_+R6{>y+kK zR~PS&E>1759?jm)PhUKG_vYkg@#q=8@%rTdUDW&NXV!1JS^RLbJlNIZ7~FNVI6XbT zJzE|O+;vXNu-#pUXY<$f7K3JWaeH%ma=v(Xa(wfq-M3*{hxOjW<)?UcakaRzk{S<9iq9`+FYabbj{ocz$@gIDg&esFm7$Cr@_eZumOpSFaa0tD^?B z>CqQIT+Yu~m=CW=yzYCFa{KYg+yB8==C?nboF5)9E*IzYT5k?tlQi`?-CW%wk>gi8 zKRUX-njihxo^nu1p#?lUqBpR(T#^FNCPdU06x(cRym)%Iu&FRm`%T)bYK!-?UgoW3*34EQ+>=Xm+!;k)_i>HX4jeQ|qr zw76$Ezj!oWqKkA7>9hHd?ZS9z_V%uTt$gx-FK)c}i)X7V`ip0@>}xN8&o8=fo7Vu} z!2f+M(l_uYea{*6C)4+#Mat#AuipFN**zbAdvbVladXcNH&>)BE-$WbrpX2LBlCO4 zxTK@!^6KLF9_7$(AtUQ>aY-ln)!E7Qd+vXEwV40u_~PC9w)fHCq?pg=r%R`q#)qX| zp6`2ZJ6l{|+;`&8ZO4nF`Hx!+SMFOLZ`gF_`g>9E#n8QEOr2lfKf$fm@=yG`_X*nk z@;(!b?Crywlgq=^gJQ#CT+h!A7q4EO-v01D%Y*MM*3Et9Prqra2Yov~w|CyZ*>KyO zyn{c@Z|;3veBX7y2hQ(LhHtue{~zD~BUi_V$M^mO`7HC}lcp#JXd}EmY47FL{PY@~ z@^pkOSz*u)JDdM-bHAl_O&-d=$e4e-IK4;A>#fi-C({hsbNA`R`wXgA_k4DA&u3@1_k4JM z--lOkF4X-W>-*+(-*;cn&(7{M#>ri{Pc?02TmD~D<%5`&_r3EIbKi&dz7O4fANqSf zylxXhpP73;vztGAso$d*Uz+#bVBdFxd(RD|z4blnn?5$HAD8zv1)hF!L{4VC`41;o zH@EXs4uTCwmzR(J=^swck4|st^M5?O`Sca(+Qt0rA79^m`f%lg>rEdVv35Rxz5c?9Qzx ztN&)t{^VwH=dPpq`P=#R`kkv+E^cowZ*Nwv@udI!?&O#r2|drB*`PS0vjKiMzq~v> zIhyl2q0fK!#p3!;v{HX8!-LO%eKo&)b8>Y3-O=KF0Y3jN{V*M&|9tU7`S97Z&yJ55 z$Fr9|&i;I3Z!X;PyZ6)ixcKtz;(YwE)lYBFPp)r{@k4R|aukvA^VviG@~h*;tJ!Zp z`@@%qzx(6&OUuY6$>HVc#ki7-^W&3OcP8@f{B&`1gC6OhuWql=Qhk4Mar*tq>;fQc^$KFo2<@AYH3k_J3l%9=lS(w_VF40 z?eN_R$?Ut?i<$cL;qk@o%hSbdv{>gyM;Eu}H~h&!UwioQdz$sPW!AHg$Jx_o=Zkl< z>4SsEpZ10S_g{VW>tFx=vu}U%)#u;!hxq=h-+uYs_g{WHt3TBw==t;SPtF$K-7GE- z-d>y>KW?w(;nC^*`g-;)ZStG1S&jVV;U#_X)kke?p@ z#LF>G>`U4i-xbG#e&E4nLeemdH$EP3_-VGF13>!g zhvyeJhnwc`Q(3i`H$BtFTTC(J3}1}95B5eID|~Ida*j}%4cAxR~J{agHzICe7#8N$E+`&Kd1Ac zJm~D?MH}ViqHd=Lvy-3ot29=<_Q@xk?>t zYqI~2m0~s6PB>sv+rAoU~zR#mp^^>tbFqO#qsUYf`|I- z{P>Ua)6;AI-SLNbx(DcmI5Gb-cLZL9c0N&i>E;q338@_2BV~7yQZd=U-o(FQ&J_ z-~L(q`grR%=cl~0#~&+y%;=8akXzY?emr~lVEWm5m|RzF@L)Fk-FL;#nVrx^IUH@C z7xmh~DBvIIC$ppaGDwyWW*?a+vyUwO*U^7H{Wm=R&-2+wadz>F->aU@Z)O}`zozXu z`;7Jy@7|9R{ewQ8UEiLSe`osl=OwSBrDn(R@`ay4;>_cJt$9y{sQS9_ClC z54v(_|LkI-)-UPxOJ@C&UBBe|rFE%mpYVgVX;f)GnnqfFuxYaG!DxNyB8egYhu^}| z>d!u*%};u*i1sBPPm5#TqrANjmcMf}u;d=BNZ-;pd}~*{@b+@Yl5CA4^7(>eibX;m zJ{Z3=Ub^$u)o=ak^!A6v%9q9~tJC9?q33*<;wL9S*Axb{zkDxUMT*M zA7*WU_LQ@q9UOe}NxA#+M|bX;cIdB8ZrB0&{^IlU!0kuJ!)aC?X!zHQi_5Y(51QgR zc>JU;(8o7#PReVk)8Un6b^i73*~|J)W@W@a5`TJqFndV{k2yc4x3M@oBoF2AYQd8( zi_f<_f6hNvw$9@x%L;48)Bkko=XgS!e{P)ky+1c0*Tzxa_j~0qDw|?<=f}z?{l^YwOFveBi|-hJYleU3LHm`@E-x>rvEECfKSTba#;6Q z?0b~6^KrF$A3Rvv*RS~F(f4@pfb4|v-{+%X&*oQ)+4bVjx1`rj=BLGcx_PshossEB zca9&N{y2Mgbwa+{`RvsRSuA`O4Rx@3|0#K)_ukKU{Wv=-6X!2n&>vUj6B?)-=Lbcl zd{j*4m9Q{xl=fT?MvY$W(pMbtD7v%!Z8EfYkQx+UGR>ZGo?>`3ePN*KogVyL{rvIL zwSr|i2%})pLw?M1^k8=97sgeb#vU$@UyUR4!>m6$}m5b zBjG_=wC}GLi)zgMRJQ9+#kVLX%6ML|C3H~zo{u>L_@o6XKK^3dN{^xF3;>q&O zcRrk=3dJ1nldJ;9?g_0y3+&8h-E4pO@T;%C`hN7{`H5IKc$?9KjE6n#;W0LGUANAs zlMO%{>i3KJasN`aLE4>F442}H<+ABPzS z4@VEQI-q5?uNOD`!EY{Z$tCP+VN?PSm*QQcqqY<}Ah+;z@uG}TT*T9Pi2)p_CyKN< z{ePWeUG?#P4z7J)ke9{htQS9@pB_~ol;bwzGSZ#w5{=jCGVKp`f6iAoCf~jy`LiX_ z|C+sE`tt0kZTRJRbQk&P$xIE8CqXIkore#581^rBJ*|_`%UZf}vv%dY$n<15{;b%1 zZ4bit#P8wxcCY8jxVlBCSt7?@8{fv)qxC<&!3U$%*ByWShQIY-oYTP9JThJsGwB@yXj0&a;oo zi?58();0#M3!9SHKhkk^HhV)BI@zCe;-0*`BB%7Y-!?3U@$0P2`H(AvF5NpSM3U{Z zTQW~yk?Fsw$9+9Vx8UjVo5zzWa2H_PjDaeq^=FT0dt8?Y z+2`}i`O(SEk6*p|dchA^qHmuryHKCsUeR%JGm1yq#8Xn@`E$Pf8_q5LKa0g>3A&7{ zM^8}`Dc7rSb$K>)Cuy0ZelFee4J>`nKIU<6F8I$LeVTpT5mJY*NZ8<9?tG_hPrlfH z>SLbJRsB~Pic>9P-lgb6zPpO~^<)6B4Ka(J%n`*bUf0qDHxqT(_Qor`>CV=CFwUSf6UKc zlh-!x`9F~KEq?f{T=~QN^tNr+780Eo({GA~j(0vAhj?4Q@R4SVxayvpCxMmt?>>Js zzbf``8SSFxo@uy)am3-~;=7yUI_jjJ_~x>7<&lbhhR^k98truTv7SFKQRc&L+r51; z&T=W*Pde}I&)Ve{?&ph5%|9Spu3G_bizK`{xgw8vIn00ej_U>e^6_2kp_$yHB>Yt0 z?$WWyFP41FS(nsb)vWqmDQEElg5AV&3&BRxyuB=UZL=oEhhHz=9V|_D)PmE`Kbei= zuE=@a8e8v)_Xz)kYI~6b(d_aQ-a4~cO`|LyhxKr)Z)4nE^bW|5I9(jGHl2^Eigee} z>B-Tb=ps#b$&dNw{Byp3u#`=oecb)6apX4e_`NZ@^vyZ{@2Ks^By9Z(*^X>8Oy4Sh zupz)ETCq-OUmZO;q760s_+$F}+v(RxOOW$c|5ZGw*%;CN^kKVJOsMkRW>&JrvHa<~ zH|z&;im44WDd%FMkS0I8xGZm!|A$2V#jO72m+ddlXSyj#{!YDpG^Cwg686D7EpESE=vx@zv-_DP|`R?C`**D|&pR(adT7#s4 z&f}-w&JK>|mnS##)5oiiHLi2{>GnLF#e8`>C5h?ZBR=MkpL%vs-Yvi3w@>)S=Z~Hg zW3&8cd0nb6u)MDQR4Qri*^3vmrym+C?8!qV-y6~tj&PUg@m@BVf z`A7b1U~SF2h6kZfXsVCdcJ9N>-kq?QdG&f6sowJG(hvRT`J)z<;pbmjpVc2*_PN^9 z((q)O9ULuXWI46?^Orw=zUCYL{`UNQOyt!_=@}VTB|rXP%${(W%co0g)PH6i^OVQz z`-G(Q`1bN(dZJ>EFS&HQ4rFFsygPXG&Fu}R{>~O>7wplOtWsTp(U0P3l~4i8%3_SY z{QRTqpVRD~%=(!3%Gbvh=g!9CiD$?(nk0EUwdw=)cGtsfyEQzyI|go-R%o9PHq%e;>Z8nYGcD zCjQYiyXCwY{$srDlTZGufB%j+t<3ee^FJ-VIJs)(N&CE{%}7oE`rp1Hxf>m+@srRNVzSq(hAU|WMTm z^ZxPseVS>*0C3T4cK-x^JOAP2j2-2b z`t#F^Yo7e$C+&`Z{pR}v^6Gg-X8oDEk<-lAJ29`X z&gl!ws<%#mwDi7P-28U_`uyZo6%Pj6EPYH5_sy$U^e0RIq%F|zfQ)#(yZ^D_o5k#X zJeg~K>F%stjndqd$alNM=Mw`A?+)6rfRpBL%K2uBB5=V+pXh@nDXZV9#x?2AVe!M_ z=%B7&zx^kYg7M%k*q_lfIvXQb%bhgu1l^GN)agM!mu z+NpQM?GCnW`B%myQUCC-TK5Am;!=d*ee29mx3a{ud)BzSZNGTNmeE~AeRE~64=;}v zwZ49M^XQ)*J|rLGOOpHB8?vtEuh_EUh$K6Y9MC2SWRHOk$}yuhdozE#xD%wD0Gi9u zvn2%HgZp8w4OCZD$kFiS`6!vI6Ts8R}3xPPt~UUY1=34>(}LxQ;qyd39~cUkloqEe3HTueaOQf zEQZ%ZfgLjM!x@PukMOvz#&WD@T85S2&|m(l1$ejo?C;8Be>!XEO%us>q=uA& zXt?Nxq~bW7)q}HMGMrI<&^!dciDZW8We=Mp4VUV0X~;Rrrss#O{J3~ejdp|bS@LS> zRRm}1aP)4IlT1&CF!*T4;j}Y@)}qBTy#7^;qZxdVND95or0Qr-b;?7EPBc3;n4DZ0 z&uiMUEQFhes~7GW&+se#BX<@5U2|RMvvc(%{-;Rfm_Pi%V zdyHO1P;S%#Y@cP>;X_-NH$pQj5}Aw=E9Ge*4V6PZ8+{x+{YN%GQpwIXLxt@!D^$vX z9@ytPpduBmgi0@ykc>|pX#HXonW3JH3me+;P38dE1G4E^GL!YVfTWUx7afsL$qn!- zjk5<2x+mTCegKcKn>m`>=>H0dfCjTsnRLj$x$xq38lE0L+Ou3M1Z>B97 z2={s!TWA->`k+mZHnTHYs_LVv^CR;h7%vk)a)YcLwI3aEIUCV%q^z6?P5Y5D&_eAO z1{L%8xMb)?8$@rzu+vu$N_L%Nlqgdj)8u~Bd&y4Z1<|SNLi5oaok~`w3A7>uNR6+S zB*mE|lN5ehYumde8^{aats=k5j?0(W4brlmW@wCD&v91tN}>lsBxAe!-Y_5h2-mSyo#bX%T`aUHi2iCC>xo|bF7l9^{6;ZC$nzJld{#FC)YkC zD>FuI7*aiNpOR5;mCCa4z@UP6H7@1JIm1NN*4L%lt!#?Hx4OiSuB`bz!>XcL{B}$WMokrUjFeEr(NQ* zY_v#2)EtCS^p<5Q4L;6vHNROYWSO%|FV@A}5-y33O4&9eE6J-WU@(Q7(}vEbX~ooRD|J7wz;*{&446hUglbnuNzafzdem-MFB%L zN2?X2RXNjSlOtcR+TJb>K@0sLJJ@PKK6L}hiYNu)Ndq*Op5y(pAb;k4)dET!>yw#3 ztj}E&I*xfe;ae>ci*a(KtYnS>FP(1gymm#s$hHL8%5Ck)c@A1;_i!|+1(r2OyF!+w zA=Qvf8!ysvAvr8)?Xs_tThi@O$<~gIp5*GWO?%8FEev(hCJQwIp6n20ZWRai$p#%C zmoz<@^fIH7MXx0y>Cs)zLbt%OTQKEF{Jp}mmDNqAQ%wt(&7qRi&u~+IjzpU@yl{r( zkLoG97uXXN#zcm!`hZ>!A&5K|nqG{`Pvb?|5l+XVDsneELZq*>)S@E0!t@m+J6x9E zU=8nd?Bi)843Ba!qvJ5>40h6}m-oXYF@v|V^nquyU{qQ3Zb+rdbOL*hCXLhc9PCe` z1H`h{t9Aw*!%CPbiFBYGs2C*+BCTaJfpRX zB1OPylIm!XpOKA;QXqz3+7-!WCkq*pW~%r(|2$p5f$Jh>6ljI-lgz47HUeg;;(=9gto~@LFg{W)5<-V8qFr4!;%ceaHc(CXu@P;wIMbxM(Zaz|Bi7B%^_=sNN>oFV;UFWZI)RRpC$d-p z`>3%#F0CHvF46J@TCvp3@B-h7GAwGyWcG}*>=~dPWhZ6IgKGH95{LYyFi%7;d7(D z+A%&V)5;8kZXrHJYE)*ln8EZ2Ul@!uZJJ0Aw;Zte|Ne!eg#Nsf5*wxRg){goBl>iziBqv>U zmE&X>#w(NLz|r&2&3P*`2Ut98(i40%XDgjvXy-RWvV_^q9O&J))0+iH2GL}kQ%TW} zK}{=E@tLFh-CAL|mk=}0L7$de=d?x^V$$izcD|<6GC#V=504z8YATsdBkjc}km`yh zFak{)bSNbe6ClvZ@|&E;X%TgP)zTCqrwwh7$mvKgN2us&QmNG(a9z~Bc$@c|Q{>>P z7J*Ehk&x*=Qp{v+*XfZg>MYzJ{7PLfQd2>elgwNJ(v0so!XbqwP-3`yJ&DNn%hEVi z9NGjq{uq-G8bju{t)YSf-PTex6{+OV!)QValJiYfmZKWHaPergU{z?KKr0K58b;Mr z&wvzPj6$P;;{x8;ZUTiU%+={3gBC@Cp}zG;2ALwzpB{Y%o+YwoRe9d?QOyK+UycIIjxAU2AzSq~=P}aU_IhGCVPx z+){Kl3-zdDlvhP%(Ok3j!trSR+IVy#DJ`tN4(yKRsjgm$szME;&T?AHM9Au+Ol01G zmI*7qo9uDP8V#7MSTs0@yO_hAa1l@!O(cYKSkec9G7H z1<>{ES~gK=;d)DEch9kt$!5i9_vAyb-q2DHm8*&C*~aCaT3W?UYVAT1n5vrbxe?nuw24%UoTTEj&?nrm9X zkSpkgPn-;cCR``-BH57*n2VS+OR@n-1Zr8)(cLUlPl`cSDNeiB+a5WjQ^U&;X^z3^ zjfT!&5Oe zTMI2|P2&a8aG6uPH8es7y_Z_d9M)_Zgi?Z_WxA9h(G5Vs&ZRK5%N|?oFmRfyuu%MI z$b(fAphXYHh$5wqt9#s(VRJS}f%&%EkL|M+>8N8c`Gb&{kFi z!yIV7r#So|1RIjOM)FbMIWXbX5$OmdE9Xlvlu01HS$r|dI2|dIZ z|3JFE8qH*odmV+EfD2xF**=F|WY`Rr<=EDb{7EO{Rx+FcoKQDPmL6imr=CG2@g!rt zjHa}Jf!hn@xbhYd5y_PY4aQ0tA&-D3ev1TcD3U1S$BF z3}w?bl_9$zYjLh!*K8OqrV|oHm+@jl^KgAmmX_8fCQ)e7f?$KJ(6ON8CagclAB1Tq z&9?Vs=lYbTwF8}Bg`w*zi_z+#okfw%N@xBSW$kf7MOrCJm04fnl*kg3_%qZsHAGM5 zT0kLuj?21?X|$;($cnScAc(QPVlJIfvhWu-+o9yWbT7XI?u_^n+(&kjgqz zNET$Tm!V&_j#ohXLLyOSw{NhDQZ+9F3v!k{bv`mWew_?2!$fl-F4e|q*>O%LBpDoT zI?jcZUxCYuYs8sxmtF=2^-SSdc?OuSO38BMj4f~4K1Dg@P2z48#`JD7)=9~)@~H31 zX5(5S*=FOu54HgjidJ3F{jS!;Bh# z1S4N%Cx&GWUvWXDvze7rS*sRri5ymw0TmQ!l$0m1rj+84IanLdP2sYXy;(Bw+J-fG z5QhCri@zFk<+EGJa>K@0?vXU6Ly!$uXrlAqs!t2=*_gs)hdL+c1Zb4qq?naf!i1P& z&vD8}XqhF?Ua8M+@|%Se4cv@RyIyEgn6_mvB(vwzJdGHb>RGmT>3sEZ30xq=wJ?i) z>JLn=voIrJ81~*mn>4l)C7?^7O1IDr_jQfJ9s}ImE40uOXRxBQ&Lp$cbyg`d<)xvy z)I&j8lcILQKA2o-F}@I9OP8a#?#EVRIdieCv@D4=OpS%pliMI;v*k9O4FgKLFb5gZ zh|b;Edi5FxN6RAX^nk%t9#PsHUf7@}aBJgww6RxZWo}i;H#dYT>1LZ{=!d5q2I_DH zu3r(B@{@87ZmH(XX=#*{N$-s5J#?}XGHG$(p%M3zIUcf5+h?xqj6F)KY?3{2 zRXSXl3IDvDD9uhVH!Y-_EP$XTHc^|Td{EZ*=j9SlCvL|RbnDN>tPR3i9kR|`Q&*+1 zOBf?%k{VYb25jd`*;tu^tYZS0087Z6!AEZ+f${clfVf`b2+*aAos@H_0%Tf=yEN&^ zsgj0H<0>U#7LeOPMbqJ5bbJVD=_9wSYaP`~s849@(iYA+_{rT8ww4)lof9`o9Arf& zEX9q)ATW8XYksJ5Y(kLwu32>BY1a-}N35lGm*PTdb5H=oRRp(91oigwvdTA~;d7UPf3m2uy zQ`K5_lFBzi7mHg0G=>1K=yz5)J+d2ZX9%EwBp;!nv!qKUkGoBa9!CMks~0WxzC~AjR^~Io^zLaxsA z-NF71C@u8_=Z;b?EUs9rH0F#qk6Na*3glY3{=_QCAP`JP-CM>nNqvw3@(OycopGM? zy(UP*h_BM z6e1y>j(txnbb%Xu3u6Y%zSO9p5`PBM zO7BhT?OcRBqufj<*1gN9<|J$x=Q#FI)6tn}pk=z0t+Phq!ohZ}gP5gWx5x(LB&9Jh z?r3MGszonlRV8cO^};bms))TK-I1lFRjn{SJe7P#_A`Z0Ax`PkWNKtC9GM-?xVM_@ z$ZW4AEhXj9xkmnj8nloJkg+_@sNMxyOKJHHCj)D&p5CmqZxVY&raI;&l`4bHkP#oE zk5hBEBmwns`Doj=PnjiMru3M2x3g%FD>ztL+MTACRnIzc(oIR5bC3_zcoxVYFkaf7 zgF#FURK{vbTD?a$nVmpyE?Frk%5y5Z4(K^zC#8W%sc}t_BswVzrKMxCTcnZg@hok7 zW*Vr`bLp&5yD*{Cl$v!+EGF&0vec@T`!QKzl>^uGo7NF$B>T4FBI_2`Wm7{~^2CJ~ zUBzT>ZY6HH?kmiXZEz=ZQn~kLGlZB%BM56^IH=ni-E#MOEo@cBeM@trxpl&r_?SLz z`Y-vv!C}rw>BfjvK+aNJ83%zHxp!hHju4x|p?}}#ITBMY2sMl%M+kMOd@Qeq?sR7b%JjvP7IQP>v{(-a=WsZ)(GcD&-j#UqOGu~h5L)8 z#)lf2w@lhesr2`)Zd0&VbQh2l=!j7|@&2!(k%ytG6?xuH=L z(Ot<*wmYR*+%H@eMU3L=WzbjGM^Oj7(}= z5Hy^u;EO>$xkX$!GAv|Nw-f{sTJ*v zec=UfBD4GFCT^K5>IKiIf6BebAUSKo8mhwl+)))AE)njsf&-|9ECrV*r2*vFSBn>T zhJeT-8s2lnt7n`z+LWZ?(m_Y1U2BNaqBhr&|Ned=&n>E}xw0#Cr5CvlNHjgg)UkDX znPbk9>9ISNI!`^B7g5$J>M7Uhw4gdyVF)otS#f}`wZKqAa>8g;B4aVMd^?v^3fW-j z8A%uC&Q%kI5F93_@BGic@&?GpQ?Bw|lM6`V;-!8@uILet1Vxc**DTJ z4(MhpuRaT%$Uq6(k#Ip*%H7)I!R39ML+?Mwlu1U~+KHP#>m_?s8X|S3v#pQSIzk%M zYWc-EdvM*W&Ivv|_q9mX`Jnw~V8$>MAoGuh3+6 zacH14_GPlH*%8CW8p@p9aHnLdpum*6LCOv6W!a`uZQGMMLz2#pc3R{3Fm_PF!cogb z^F5nL8^y~kQZgAs$>22lI_dn#msfGAe@K?Wak-W?_go^)RtwwV6xxv{eSsmR5>3Sc zOmC;z1z~-X&11*SR`wlIlA36#`=*Y$JGFScMhL_7AzH{c=gF3`exkjP!v3Hnz@fW; z+&5Rae$3Ml@{|ZuQagw|+^G8Y7@RPq`IPb2Q%x2>y_D1`hY>{D6qc8^GR|peok#kAi)CXgtL8p;!UD)rrC2el1^l6f#4FKHMLS%9qJ*{@vvxLX$T3s3uu|JHjd zl)7=ZkHpR5a)h1(^jt0>43g*)RO_`S(&|E^D`RolAIudHL_rciq^Vq+V}7FMip835 zkzq63TY2{0!B`om8p;ihA=g5T7PIoJR>~qJlh9Fz(q?Z3 zh@u)FTV#`02of}$I&CN;M%fEpBeETX%2S^#X{jgod1{nwC7vy8JHz_Du_Lez9i7zn zqdix(U!bGIN$Zn1msOQLQ~3#T|D2a?WEEpgfiQuhVr$PGf|TBkhKsG4WXW&K49PK) zk-A+VC7-iw$=f&u!Gs;@Se8ls#if=hLQn-`T&FxamvsnD7jAK)rf!Wv%-vuDqf#3( zjk$f3w1&Xs#=D-4nES$VmaW1xO3N`9q$K#RkzX^dv9x7Wn9ie8W}HQ2qoqtNc0X0v zv1epT&piZTWb|Zg_}Mfy!H{xWvVw}81)q*#X?nJJfuXTf`ye$9f*%^47#lJ|>b}Bl z*%-hS1AIkL=133d8<8hhhlm!BJwR8Fp|RLRMk;OTP^-~RGKjKpa!g;+dPDGjlliA4 zCc0V8h3rvg)N@zbR7n(57@U(~{0seBjYDz?mP^t%VH<2NkuFtI$O1=0nt8@e{Gte! zmO1p;aNE3prIDZl`Ov-XhmftA*_&)=ybrWVf)qv1ZAt1j<4BqmMbESu6|`x&mcz?? zKKg3RTMj%3$zGYk)7InBvi1|Q(b8~A_0ABbgQk$Yk5x;rDKy15k^vc+P_?JB3>U2k zak+F-#JJqhT?zTo!%$7!!nBaG5dYrFv|T27mZF2w&>~e#5G6Ejbsqcv{8-w@86hi* zVTYyX6ccwPu|i52qmrN6y2zXt%f#8P4;Q3ZGVViSCj1C111l{^(z;cJ@MLAv;}(k5 zCg9TfDC2+$91(7KS1#)CQm}eRt-C5G7Nv0E#3`Z%zR~J_-uo?@TavHb!g5>}5{2}2 zOp$4NR}E!GOsLF_9D|Roc3jD7^%9pqH{2o3Hf5Qf&t$5!r3e|97=hf443?TKs&{1O&)&;VS65IHQX-?# zOxr@reih6_%UZf$XdwZDRUMbchO^QVYngk0r4IK`rF>jAJcn!*t0oas>DH8MN3$L7<8YXXPp+9Eob|*7{>>P9i%z92a-lPQz`ZuoEmd2W-H!5J}qz zF_Eq`)amo1lS$ZbhFtur?L#rJvJ~x+>emeE8$&op{(&)EIQcM(L7`Z)9Y90|oX@xKfw#{ts{WFk?k!b>M+iY8ftmed+ zjFpu!rPZNia_Xq0u_{*)hulkB8oMdw=f0h3N|={q)P%3m3_5~rbV5-{oY2V~eXONS z2uhC#=9<;@!iJuiYl<5boS6`W?9601<`CS(JS0;rOaj~+W@>ILBxJND7oir}F=dc2 z{LQq6s)fGD;gBAfoMm-e-OE()Ec?}!QoGVeubK^bK!pU)&iI&(q z=q{iSgO%Cyw0S4Ox>6D&Q+^!BodRFnqfJ=J#vGt(netBw>uR{OM15Y*6t`X&cnwoT zgPad5tXXFLZW`+i?G+_&F&IZ$$Vvd=rHyb{1DXj=>ZPC?wnl6I-WFvo3mBLli8RdN zBusN~bG%e55gb>p2u&BVF0%JM-)^+9aEdVnrbeu|yP~j(P{9MVSZPU>doAyu>vZgG zj#8BJW(RJLG6is=xOgSx4#MN(-6<_CP9lxpa|w#uj!Gdty+iHO#BPnW{D*s1xAGNk zckZNn*w!v|wGXTj^2V~&M&pHEJF2sgZ_1Yv<5pr52I)Q_O&?P$@v`jy3M&>lFy4E} zSyG8k*l{KdS*eM5B|0PJQgyL2rH~dA#w8hS)V=*U7$H2snZdhG78jYWUdmUhM>?V( zOAVBdLgYF#2ILlo9khx<@@x(^#j001kCKA4b11kQ-L@4aoY zL{1$=VWgOLtxqmYoC{J22)%^{Trcecg+;T4s<|_M6v`ASAUSt(EUs-6a&#mPC@xd0 z$|6_{a&dWyVnWD_#Vs#w@A$@1Cus>Y$09;!$jj1F7FGf|cAT!4A~_iZ(NYUpi4jA* z#ip*XT*)Iv|MRiiH!v58v7OJ)HHF8c!G~=fRcVt!yn>BJBWv@3T!%9e0rc2nMQKfK|k(5@f!7I2D zCCd6iklY$q%O^P3Ez2<$!X(?fW=1EgKVv5~R*E<7ZY(vKNgZcbEey{-ue30M8H6h3 za4aMw!cCSLbv=&9X$B=6kBKu{A$cLNk$IFx*XUv6*NRyJ!R9h@-3xgG6G=L0Sx0Kq zqr*EWDVu(#on|^Ia!f)!Q0m+}_Km|4N!HmQxb6)xrb(9f;5x4s#(v7wVnWI(db>__ z#zL;rvT|Tq8_@Z|MJqZX8Mf7Xp9RJW1TkY$#s4$?m$b88WVm^1!)0OHABI}`wsv%) z2`MTV#?(3oSO)wG$qyp~q+?4VXCXy^;flNF739*+Si;Z4&2Ag@5^H%`!h_icRD(if zH3+j$W~u2Ym)Qhyh4w%X>)Vk=Lkna7T2|%;V>QTvq@Lk(x;L%&QiqDSt?v$6EN!|)^JDa3KQj{Z{z!SrhBVQ^b07Ec zH>m2U6J$zXB~5OVN!75lmOD?~3()O>u zYxzR-9fb{u$pp2rF)Y(o2`Y*kvgNFMo|4=wXd)dgdGY-@|T6! zyu=jgq4Ob2nf5FjL#_D&$##;V49HS8w$tLVx)SLErkQHoJfsVeoVf<5K_4>n zL@8mX33{c~>mZxnX<1DrtEO0u`o!GX!oqLwI{RcyBzwY+*K~-7dZcliu^=sV@Jx%+ z3UC$Kyh^C4=w;-_+mHhDR0s#;xKgv5bK&_2(iyr2=;j!#%2JvXdc=C_avwQi7Lmqt zp@lTu*vw0C5OIvYR|u2)E6jw^c)m3r=7u|7=CnD6mo~637x~M$UYW8c*60#5YD8Iv z!x@qk@1{(c3<^JbEU_IMO6VSNe4v3M`Owu#+|i{f7Eag+xfr=^Tx;{jWh~i?dr!3v zjhZ_o%jAS95jv$77uk4W9V)luXuW+o_u^&dBU#?ccaB#MjR?t1xC?YA=NTJJ3n>7r zhT{0L@0)$ib4!`PS9k;kHO6f#cH0Ii5RFSPRG0|%lF@R?$WB61T2}}M)UHDw zO799K?G?rCpR<{upGizZsn`@<>cte~Tg12?ne*a~B<%L}Scamb*Gp3;o|6fEhSFAz zOmORS?{AkF=_a+rz0aMJjhQ*bGjtR4PYk26AWPku+Cz?2c92!3GLdEHk+ovNz2dy+ zdZu$Fl>jC{*}sxDn$UR+JdDhi&Pw}2(5aMb@X(dE5W)?TdZS+^E3+nw`)YKQRve79 zLlGB_btoxA7o}BMG`-lFiNvw`r={&rBa&rK_)-BSEIjUgKUlb}&`;IO&f4pBw724N zggg}h74X@TENUO%U z`BC(7N|+nrxo-V(%}I1ZI-#;fV(TBkrQ0%pdLVPHp26JH-YFqlSqQ0DI7pkIl|D~3 zpTMJ;vv*9#HX00Jc#YY~VrsM>9L107Z@{}y zi8?|_{mKhITRj_7`dM-HR3`mAu3#wMp%qtSH3zPwXk@WnE^l)E=w$|1Ay$n`#X9pS z_m>oIxXi{tn&#((X)QBY+p9f!I~#G8h;Q8bdqXFw>#KOcG*Nv^BPHC1GuReQ^c+nU^3ic) zjBcwr)-+klt(d0v%XH8M;bG~SHn`1@8L_1^WJjw*iOF&EN=Q%1MRz()d>Y0G-E(>k zy>;W$;t9%%7Rh0AsRvAo{St&}3*S2w@OVj9P);_kjm-lw?3>FxBo{cMk$SvDd6`xv zTYRY1>4v-omqfK=T=_V@Tjr`v(#keI%WEu=ER7^>FjQKcx8o=~VIa&gVP0sbk<-$x z#`-?@v_3b(7M9I(dzX4#GO3F+c1i||(KQwCxyy*Kr!(h3TUW$N!t&Qk9{KjFx-q1s zwXivzF8SWjkYzDDA-8AeYNUtuQpyW1z-Z?hSBn^FD^op$Toa9j=Tm5>F*{!4Z4GRL zD{%le_=>U!OcN+2zs^-3vw9%|H3{hk(p0=-7y}|>LtvJq+CSc@pKO4?SN)N<0T z(k7Wfdto$|(` z-j$po)Art28dL5>yqGBhHW zV00`js{t?X!0a2VPNr=q4Cc}p%CstG4r<5_4jv*@+kiRjw2ZIX^Fdk3hfCvMCD8;i zFlkuR@VPRbOSW1bIwvDjZrIZrA38NCk53U5%fy zwS2_3!C| zsTX0p1P-vaSTI=^_p)GZV~LU$Zf%koE~mYaI+2OAOy9V|hHt#Na%w1m%wjF9eq{2* zM(fS+LnliWGc4DuR)ZhzXB6GWwB^8ARRqdQ@sQlhAhq6#xfI_?n5($3T~7pTPD+az zM@W7tkn>qPEoVouy;W_J8jZ1GkD1L)3wK2vI`o92D?$e-@M+r{f`vgy&0|U*S<`Bu zT~tEiMDALeJ5tkmBlP!}yj%CvQ5Lp{yh)pT5v-I0m|2Z_n%Qv0ZIp!uIGN^pm@D5O zR@r9p^q@M4Hxq2hpd!qEpeqWJJA(;1RDRfw z#K(nURnh|KC5JyJ4$}T_p}Axn5tV zxqMzYK~nW5PW1L#$bZb9W6x>usU(FIaq{1HP&C&Jh?{rC!T0zNokdw{RBn0fh#3)0?{p=GTsw}+7(No>Bf+3{YJa*%{!YP-k9iZ)46<#r-_HZ4asNk*%Bh^Ky^I zB=iGA;~OXdOC$2LxL;vI%f`gLmz)%%nNme~kYYAbn9^lbdL#BuoCXu-BT8VdMq9EX zFGLvdcY4eQRqHeh5i;6kCc>J)(B4OBuqw9T7jKTN#Kqphw}aAfw*@bS8fM+uAJS+e zNX9Gt$GNwfio$A9%VjDJ63tK+S+67}&i1|f$}tjL7{}Fv3JsAF6&)m!KrXLXpB*Ql zeUcV)_4*Qyx@0fr)5&Ja!3azBIFgZF#Zs{eqwU{-538CjnrZZ-I5Hg7lucAZbRhRg zZ(Z0NH_w&fW)oQ%b?pK-W0D=abdn`+J9m;jj;C5d}}7fY>+cMGyK&6jj z>^-#QtYl2^-Awz$&@XA&gUi4w-sk3d$+RnAzPD8Xbi{KTR`KGAkhlt~1F~OEo8hyU-(Q zcMKIK z%9$>^nc%)qD~PI3xrIYJBh|>ED8x#)4mO^>RWT2q3AzJPq7ccgCPYPvfeBH0+<~+6 z3v7j zHT9sRtzy)aIOg<@Ny64~WN0+y7wHss!oET#^i*JBeT^~?m1!qK^AH%&X=KSeE^*4O zWwqthqKu`Kvk0d3;50N>S&&$B7Qy$f8rJ?5L@U2|#-m-AzaA}4Pp@a^+;pCv^WxR3 z>%|TIjB0=XvHbmP{`&mn)ydKP=H!CzCFy!Ozg`^9uNL$2&7tthogckf&@Y)sbzPNh)A`xUzk8Tug(|O*X3WUD{y&oezCW|w+zER9Dl=Jut8}n}5lEq+s{vkx zzs8CZ-Msv4@83D92S}GuZAwZouAI$u1pGE z{KYf=c9q~~{GNd{>n6=67lMR4(rhg!hW}2aIloVunNaK*xN4A$J1F@MNs`S-7IKLj#Hs9rO? zitc526p#-KuWE~h$r^mw;>$?NqCv_`BY|R247wGHq|4~4SGyER+fV#thtflK^~5ht zwf&x)_*x?wi4h;;Nbfm^#Fx2R&{YGkDtKN)0|Vddu_=M12_54hAltw}+W=}^Ze)xM zft?=iuItjV_H^xVXKbX|6J4sASs$Ik5uW)TUd8645Afy$uLgXKYkV1N-Uu~s2vAZL zJm29_?vYeSrQlT!$JM(OU_TiHW+?TrYu0ILwX_!ky!v*gt4J1-)zCVH+7y|gR%7Ed zZn(Tbs<9~>k(ec9AV4jtp)Fycbs7~G>99*N4U>To$L1(^LIP?8o9#zP03O5KG#Lpb zx@w^CdV@sI7-UQsZK3YXFaiNh0cGG-qzaLQ1q&Up9H9q=wgU_aWH_kbr7*`yn9Z2A zzhmv@F>bdDVIDImA5fMxjzb|uY@o&9@wu*$EGKNK1{|`&-X8Q9vET2YT^gXm4Nzgj z$bs9b@0BJCpn~82_e@x!G;U$RY8cdn(bfPXvzobQ(am_^4Tn7r9wZz*NE<9$q{=e% z@u4bYUSDvq!`MO8J9Vpa*N~BG)z&fqoV4GQ!#=~%ki}Xr;RvRN;*_9%g9hxXhuuRG z!N98yUiI)QvM8}dilPD7$AZe(Kn?45>rH9391l>+uPIYCq@ef2or*A^9^tuap_8RE zzKRuI!mfP6IyPbLosdX5s0s}-OO1uTyvDjT?o|4gQcZ3Inca~-CJeKCICNwmET5RKf7Rfsxw;wQ0%<-ix%M z*AO9s?u<}xV$pSQfStPax~Ham;kC;^bd}wgkg0)K663JwMtBv;QiglN1qDZdVOwa- zCWweh&>VIS>QX3U@Ni#!v`I=6yqe(%yESC}G9I8n{MQhGPVbB8!bEA(&<@z(FG0m^ zu_A@hE9mJ5=;;UO=?CcPLm7oI6azC_9_F4jg!P%YTN5@+&K4JzhBar4`)2G-<}_fj zfp#K1?kx@rKw;XHBh5HInsHnJ@0HcyLRWhVTCq05d!e&t@YS?ap`21n-1#M}DNbjZ z^?F|nR_Iqb>{r2@s)Lz(1L0K$BA*ikye6oTQ^q4;kaUEHJ_Joc)d>%Bn|2B{)oD7& z{n*p-P9Q(*Dv@}S+mgqNIx{x0-#GInPiyo$pC5L)8k>F#h+2=0^!r8Hs(8`+vZVelSI z7C{TrLfp0At;#f0^;2>qndX}B6ZS@SZG<%-P&YXYUxJ{0gLC&WZ(TqYV2MD0*zKUw zwk1sv;A~(NO2dd1L`ChmfJ9H}d2a8$9u-Xk1AX_!%Eb6M1+PNoh(nrCz>>#NQJ8aw z+ayM;bOXE!^&m_#VIlVrGl~OF5V~iukG0!;lrhT^UE0gvu~XgdAbB5N=|Z5LHBb#= zcnXa3ugcB+B`mnyB|-%q6E2uZTbG(38Pyv4U9g}k!m<{#TcDnql2J^vZ8S)l?hyzY zih|vMhu3Cn3^T?%Yj|(UIHV6#1<(wS)^CeDJD8%yxXj=p*w*l6k1PHPV5IpZPh9*NiA4H!Z^EdBSM5i?Ka@@Fo@4XBvgiF zq8T$?;le2cfdLt&r#$rU6SQ@q-iDrA^01K4?=}EC<+qrSGOwjoOXK%_iN8Xl!NJ(4 zfxtYEqXQTxfMI|zGn-*_AVY#O4`tM0!U+tU+ASlGT1GzmxQ@_gYCgX=G6s`KFfVGt z2HZ0AlQ78H;s6r#h+uXqE39E*bqI`!Vk8L^QiyzBHHJRCJWe?$TiUd($>To7n;f*< zOn`3AhPot3zpx6=nEWRwOi)N+6e>dvo1x?x%@$WG*UDGhn8T%Oz9?+LRoN9rT$KJhUC8XmT4Un(~Ir zSW^xOxp{)-6<%(e76IrX&wH>|0|9<06iog@QhG8HabX@0y=jEqisMwl6S?iM z27Qk928!mO0&*JygAfI_AuhPVq{PQBjBmmb0<=B@4DDcq4y^cvz(@;$8eyjpALo{> zNfZ1YAKxTjuw~W;9u8QU>##6lAPzixA)o@H)U$zr3aAD>RCpd1<-nFh78(U^L%r{A zP0Up$IP3m50p=h208cQp?Vu<)1Citq^kZOUA}$ew;v8{lBX0YWGn7V%*@0CQ8e=kG z5$|gIn-4FJQzC}!No@lt*HO{zO+XShcH2;b6Sk)8!1Nw^gP3BO)<$g@1Ukl9ZA+zL za7Rr@`tEjXJuVg7*s(AA9z!ZNkY>QBH74V58~XjiT#ngr6*?}EsR)`95!Pcw+y)pK zicpzClN5U40Twx$-KKHe3JaWD>xvQlK4Et~)K?xVH{4GR^A>C%Ilznv1|m2joLa=> zG767ix1=t>DRHcaVJlc1#}7M2vALyWj~~K%e^(P%qDp_~*&duwfo?HoIlznv(PAl2 z_yEV1UkW#IQ@EcjtgeL+N?052VALMl76t}7quZ&VdbL~;#sJs56=8A6e=mmV`)vbA z;gTVi&B2cBxMCbvmm7?%%$V5|Iz@CDgF+Op4UgN_hC7^Thn!m8?$lTEODu72u$&4HqHVhQqB}AT%>Wu`@Vxs&EMK8#Fa;G6aoQ2z0{bM>u0;utJ7;tle_Zc)!Bkxo!;aQzJPKPi@>A4)>8W z4)^eYME4L;0QXA5O!?3^OVGwhI0O(OtQ?^t)mRh5R)-3c!K-aM89ChQFhNZWQwggSDIZ=+r+k+Q zL$qr!Kf1a>dG6Hz1>+I4PXlg6RdwL+7C;^tfJB;hH;z^Sw%Ap@ss5aRSiEhuBk> z@l~jLJ-)ir5La00lVk>!H82HsCDI=n7`TbRP;E_&s5Neo42e2D3@U&w{~DXqD=ny7R$JAiy{~%HV*_!L34_A5+0fG+RzOD>-NX@mzgyGNFBgqQmjL~e z+MAf?1`ZHR7=p<~Fha#*rW#1`ZLy~VVbU6Np}>|ln1uuyoAAJnI9d<+LLK&s!h5+* zKDH~yk4giqpN0L4)b6z-UH@;U@X+aSg7C7h7-4r(KrmRVHiF@SSWUY zAfSJPvjlUZt9_F`yzr$JNHnNs-lxQn#nze*SnI&}3=C#&uq3x9C5yPO4=UvdIkw@U zjr(Na@Fc8wg0UnWcY8YLW#Vq;?7Q38zz$(=BAIpr9SMZeTYQXah$@0@3_RxIftC2s za0n2U9U%M~+mIXDAi#nXOnnT2{~PYzX-X)ni7r$Rd96o`W!Qe$7rM{@y%bD@he`7+ zbm}d(P0a=Z&<)upOyK|-9PG9Pc^W$O34%sK*s0cxdYMZn?f1D3HIp?PP{hckfyH+a za0#8C2!AWWa+3%(X2k7=UX%4Ywe1t;J|gn7WD3P>cpUNqB^~ZNsbx+o}f005SG66ngq{ASv% z4KNiAagziUP@Tr!P?h2E_6FD+z6t>#kY~)oq7VzqjuJE@5>(s?s_3+#C=<4HgICSA z-QyCJ+q}~NeO#(9qO(4%7rXgA0>@ccNfZ>W4#L@?4IzG51P9M*cvM3pB3XPd)Wi_w z5i!{l6g(JJ!n9C0LXdZ>anrKonwebfmgg5ja-cVcw)8rVHj1kNkYTUd5 z18v}`Zntkq3{&!$ZO54RqL)9s=;q~s)tb)bhDtW*y@^*rox7m{<_1BB#T5{eZ*fN6 z;ApsKJKTvak(p+^I~arRpL*a4_YrI(0)fd*V7-sP_WAYGK8Y z^|((M_P!uo(?@KpVk&<1URs_B&JNvkm~_JI_-d#18EJ_&&yqIOpgzOy4gZaW;m?d= zM6jsLU>16}H7O1z(8j;PV!TO0hWN0wAdG@Kxx?V^R^Ekaw6H3<@r!A+u_yY4&87B@C2Vy0AYjYaqd_ zg_S-QcQ1rjEvz82FczO+U@BomvPKA`cA*k{KVvxN^2F%54Y7D=P-e`)fZY%bZZ|klZ#E19K}3+GM#D&@PFSX4aR#m{ ziaSNiCBNLu##kh%c7M3-p*i9&>c>Z`Uwo5V!59kg+Vn z2vFXwEKcd2tcPGwBN`XYz6c{MuYp2i6XwvwmMYdU|Y^!pu2LCMA#kaH#Mg z-zJWk$BbzbpvS#iB94@oi8$1H%VL}MhdIvT{?~D9ZVk-CVLVRs;U+dPf#`5$u-cwo z1CzQy9ycU*33}Yl?o>Bswai`Qz255%h!!{A!mL-Y9^65@(PKv((++#A9r3*|SOk&1 z7Satu0!|CjLJsF@%x>jTFE=)f(Exc2`_i4*;W9_u*h)ieLx9B-4rXvH3<2R&83K!7 zTq(h%X7U)R4o_uVUGAVX!UG(7Qo-+5a;GAp><1UtiiAuWtl5{~Pl7m#1Szu}?t2Nn z9*27bU>vc*U22TQcCE$04U2I=Fen6(L>8yMVTYp#>o4MN>o2mM;*@F7+9SG{l=dY~ z3Gr$XW?Y=YwZ5<}IN?Ag1|H#7Gjw@_WaIQT^on3V7~K8>Gs2~v`agN89Z_20*_s@3 zzb`cu4il;28eC_#5BWg3vGCkaFjt;nUOmAae8N2d)b@cOiv=1oAX&Rpj79d#E)XZ3 z_L#}tVS5qQ+6D+3a?p8qdIP{{1K~O*bH^A;Wj1iULt_&1ZeV(KYt4} zxC}cEU_v?v$wR!`x;wnHxJ~9xxoh&2ZAx}9pgF+~`xbv_Z!6<=)wtOp3?4;D+38?J z$-x>lhbx3}Ek?xAE@*T_vu%Ij4MfE-yzlW<=)>imMyZ(SYKbMD83xuPs!Zj(Ct)h6 z2;+w26pm9_d=-l{92f_w90u9pc!j|PcE;(g+YVzkClB*p5jNC{+3!|Xr@WQV1ONIy z_jJ|p&Epqu;PH&xw{B|ns<&<-YZ5kv;njc**xKuFDUuUAgd zts_tNsn;tEb!`wwe3Wm`q!70!k574PPWlXU7a4kX8B@duvn@e`g$A#K)`Wu_Vs)SG zK%ke3m+TM_lFIB2w+Jr3a8MQ;^zt1hOWwfefD=|Q{*XPs3f(mf-GUaUgKibn&k!-_ zV5lPOmc5aY483`A9KyN_X3Y@7zGz(x9f1H;2aQ_?#Rf)a4Q`sCHW26HvL| z|CQO0uEl|3Os9~y?F0`aQVxb_6T}nx4T=|n1Wnwnq`!|2&+ag>`@z945Mts27XOT$ z8nh>HlmOcTxIk24=%BK=Z#=93u&_MJ<8~kk*WB+oO0`r8r3aS{(zAPm_IL1nc950< z$Bl4|2}eWy2Fby~jzNOTZjfOQ59#gWOz``#6yHNa##Q3f9SG`_weo%ldEGt@gVTGW zC2{eH^;?rKtB4~5(2#|e1Llkh*sF(UZh(h=z_=@DpY9f6rS(+#f63Q1j-Iqg(S6oiQa~cY4lseR}8Gu&#=p4hBj`-iVthUv~Asl^`e7s{*fFx=I`2>zU zxebHBY$xQDurTR_5BY$b#H-zA;B{CA@N=!uIs^FLQ094sO-`KG#Bs=k&vTf9ciWfd z<2wF?8JeLdm=f&hnXr^W;l;)J?!CqOI}p>j3?gNW?>@WwUfHb^2$ z4Uc&b$$$*BX1&IkYp7^e=Z3;ltbH-ikWTXrmp53oSg@h8jkvEFMq|VHR)7`N0cYS~-Avpuae$ffXHE@_ zQom~`s69$dBpl1yP!EmcurLXM^A(uX3X=rj8W{+Z@vxNzZjwgU3CKn?CS?uD^i zHUKlF&zNg{-F)za-y5Y2rN(0_G#GC65Fg+j?v{oXB!+}5zagZ6;WMz_54!jkxB9`| zo1yujvH7rDaG^;PuT>th)@$_ZX;6DZzwY7T>apLC!%Hw0wV|THVAu<0A<_mKz_>;q z))Ux_xh&DW3FZNk+VNSQr#=;2Yq}31P1Zp8P&z6fF!wd04Z6tMMTK03Z5p+ZwHe3%_>j!P}`ZRSpB= zdDiWK{pq3RaW_g>C!hmXj+h=2=Kir=iK}JJ23B^A3cxTEgL9m?7b?66efVVXme{Qq zW!-WLfZ0RV`=0L;R2v81VSn)rlmfV46;#sDVG8ix0Gnk7Y#qQ_C_qz)>TEee|97j%F0tQcQlWb2&#g|G)O$ZCRGwI2L@L zub`cGrGNke2$*T+S7taSVWo$}kG+#fJSqM}D<#~2dicTJu#apv%?X@?3#R|m5 z!@YbD^Dca@&UewLz%~Uh-_wQRBsNxs?>Ll?E^r4>254I}Hvs((3P2_E_3n*N61 zjc4a`eplVk?LO!8U*9Au%Aawb4}1Cx&K=&A3Jyv5#HWjS7JdTS52XWM5!F6E{HM}B zrrkw+u3GOMdghbzU)|C>4fM|V{ndLbSV+dof5tK$>!{)`3g*sq5x%${z^NKivI`VC zF9`=&Ik{4pb-7R*SwIaR+-qoi%`h7|cm0l;5B(%}#uMl>WK$A(2)Vcx_x z>p0P4slbwOoMR$3Tp~qCSdP$S;^I4CI~7Q0sr6nRp`2gafPDt`*35;CkbEyUCChngK<}1kId6@=WNMHC9+!q65Aa_*FvtXjk`yqk6a3nOR}N9IEC#F- z;J>#pt`qR5u)|8>*SP>JXV;88cQDEm*3jPi_A|Zni&IcIpfFXZ2COBY&b#mo<`C%NU`EY&D^m1RF z{A*`=I5iO5;^C04*ykD^Bfx^96r8(pqHj2*!?yx!UM5(OK>wnM{S5GoLvTfX@7#jp z*@HMmH1hot*Ng&ZyVz7!S1SI-aLbipF3ni46$dK3 zk*)UJ}!9Li{D%* z3>4u2m*7;a;yVStxv+dK#2RmV+I}xAdzJXXn>GY+oIu1WJML;W6SZ{)LU7;B_!`DTL-2 za`Csp9E)3e+_S+^S!wvuhZgU!{m*cjMUcl!uxCs7);8U{g}?#K}bG)%nk-&Gp^TA0w`X=8+!5*acWGcGW2B@L+z`DWQ{p03Fx)W2kB z_NxmOVFTjwv9&9fpy6nO-9Pro!rTNX`5w#7lY(|Oh_5Yv zv)d-Yi&lcWt%xUG^08efw)PZQbX2H^Py;qngqa^7EMi&$^lyn5{;~2yW6obcO3Uez ztZt#cXHDAjx6l#@ZeX!V>!XN;2fHXrp=v>fw*@)j7=xml0cTif)CEh;h>vS<0g5js z>%BCY63^lq=lrM|>vCHG`m0a;vE>@%vV3eScx6Ed!w!Cj3co{zxxC^B7F_qOPr2Zw<#O zjDOf^RX8}S_;?F;=oM3|VCogZYTA%Qi-nKFz0|_;+I7{i?FI|q9O+m%HD0*D!=#>J zql3dY5niLg+NIzQ3XjRKC^F&i0DCZ~Q;c7L1POx?o5(^5FM?lNvC{F)7KY_y#Z@+{ z4G?9%X4{J$UPNIMKt>pKy@ok4+B}9Og1MmuYy5cCY4A zDbv_Cy@&1>iGVR=R}svb^YZA#>W0iO%%a67VR(R$E==lSsKePtg@Y7)6BeP?aTM(D z0b4}8v};&-9&&5zy_}r#TCO$P!n?EQH%){K%*S{ljHkyn;ID=HOxWogQpak-A&p6G zIDJDJMTN%>5ql#++1rTsc2JWPPnE0OyLBsa-f|Fsbx30q8kAzOFwF&(7vH#FWPiM8 z!5JNfE~IQ!_}g0XQ3GDvHOzp3rw#$%>0k@Idl?X=O;_#_CF$EZ=f8d}4aa+!lS3CG z4+K@j8~j>WrC{mZjJXx~YvKC=uOJ92;}KkbT<~|G;vPX`vDtp~*N@&B&ZCgT8C28X z< z@8-J3v%6D#zr;xGi!L!P8b_$vgbBfLu$HNO>_LY8$|}?-sgQJ3;TZ)*Y%B(qaAN-0 zgiQF}g-dV$-S6?2IpEh!KH$aiy#FJH(YoQcj4NE3tz_H7>5~r z_~9Og;^)^z8Ru#2@O1NTrM|X^lpjHzK~RUUA-QL~Tfr>%i02dVMxAjl1|>==)EB8x zxP-886XEM1m{Ak{4)7NMt_GQIe)vzPZL;lT!1o$gzD9)%{?r@Z)cx?N>?LaoSKv?p zuR>{%ipyRo+fWM*$MW$BTe|SE$Ds@JG2QEJQYZaKf{j?EZy6(CT`_!?314TZQkP&6 znJzq-;dCP53IQsH)C6TumBh1Ep8SvtK=5|Rm& z$luhn5%%K4is}(EjoRmar`Q{{LS9IPVj>k1Kr+0hAh_$mW~YS3n&1)V{4(7Tk*}Q` z$1Ml}zVY{%M7MzNdp<6DaeS00c&Liypy8Lof}&#DCZ_D;(<8inhLmB#l3*}J<`O>E zh$grLndfjfglRj6X)Aw8iq8!*1nl=iA3Hx^*hIt7%lN(xc6}9ZM(`PQ#bvMHC`%u^ zM-!ytq=HRQ@b`tphjcHQN5a`Fu)G~AC6XRDjcIG|)~V@>oOv$#{U2)2y>@5#wirIzu(zsk;8x*x zAT0g^Ia~xOFT_|cKYy&1M|>}dSLi&FrT3BSBOJrmbWsFfV#d<=SbPCCM%Zg7Kq5?r zzU&o>-cuI0J*CPX%%jO1SsmT;7W_&d>ygF_jZk$0U6{3t8=ddbn!<7=71qM= zXePlPDh0fIfXBh`Xi}ioj^Obv;Y5#xED0xMn7pB^PQ^4D!E#mgbFq?g?_jOHuF(o_ zT*_ba8tqpXmxLq$*qaf)FAH$XAn9|5H8{o)c;h3O;f=d6s6djKe`sTNLyS#^W%*q{ zG9JrbPt;OzDyPT_Vp z-b+7hG!bIUche8CpE))yyAUrZpOVKh&m42o1&Z8@Ie#2atGQOR_pTZ$T!jTTM9^QmOiYq~iE1rL)fEN9)jg_;Gil&(ftHvOcUHw zq?<_u?X}9PWut;N2Vdj*95Lq(&aX0-o5Q_69NwmagA6|9kbNi_7alnD;9Uw-*hrAS zf>kq8#J-UC9?!ONPLaEC!aGyzTaIVbg@PgsJ?Mvng+8$;DDLSYA4Tw+k2hf%2R~N- z%pYrl;>AOO{eOZJ-Fd@yL+IACzD5iTUiU9L9&Gqb5Ffi>x&UL7Xn6aLP4sH}*r!*Z zJdEIf15Sl7@xmi-d=Q@Ckt;UjEp+eFtI65eguk00i_J&Fh5jKfW8ue8Um(F#t%jxh zaYDv}37Gu_jvKHNeu6{R1Z6Y|Y{CkzJ0Qn42drj(bA{2)L;p}J2=%WKbSAklKov-J z!Bc-|iwYwh2D;!LjB%32;SUYU;5>Hr#D2-^!+di?cev=+ z;>YF?8B+uc7FEPMR6I|GhmlfnJi+P|N)gnEzm`8XhnSDvZiwDENhy~G>RbMnO%~i= zMtD$|uqi3Ntcm$!hiL33jh&|jk01*ErN9OxFmGn;1r6(1c*~t2OL2CSz9Dw$Y(R2Q zT)w$CgJgd!_mT@t5A^JEuw^-{8M5FYh3|F6i4=ba7&chS3Z8D^quB(nY7)Gv zVUl};l+QOYdwcNBR|QvsDsV^zi6>Cgh2hN~b|=S9<^nZc1k2i29C|Pl7JS=XK9*^@ zax%a9!9Q)bWJ`?zNhN)a{C1>^u_^ALpl}w>$Bb97Fe76+BJSv6o)(;^;o+@d7Ah_q zD!xaAWdj`2W;koea3(f0zHbQi*Cs5b?YmFAW5Qws`QuC2i?dmLW1I2J|H3gF=V^F8 ziR;apKR%mH@X#f}Lzmoc&b_bY7Kd#YPI`~XZ@S}#tN?sX8{otpcl6lY3o=?VrdZ)i zFIYGWc6`B=13Xhn@E|3@(-VB&UDC~Cs@HBR%T~gB=1gC7-VKvhg+*(^2PxP-9Xmn? zSdnC048UGcp#F>Cr59AWPOwBMaNnA+fi65ZU>MVUuYc%n+%%%MZ2QCb)jCCZGyo~9 z4fbaVw)+W7xL$Zd<17nTtB@|8;Gs%_hboNcSMX4!z{LUI>kdOPzCBTP1i_ zm0(Sgu|xq>-I(Q-ZiwmElIzgW=C2;jR-F1^R_2PA1#rI#C#$VsEm@fD;ef5d3Z_93 zqlS5Y4M#eh1pFC31sT?}^Y8Wz(fitdQQ1mKUrma|zDID_iu)k`oX?86uMOUFw}|zX zafXEASMc~RLzC~Bqk2P(y_Q$GZUU5vzsM}^!p#^yxR94$p!!J`oCz`O8h?tT6z(wa z5kEZr%dlh0us+Dp%sUhQ+MD0;ay|}-oW3|pN$@KUOFcL}ig@{zF;5V)2H>EyVcr3D zxQFsVE#d@;LmGZ9Y@ry^U@|;31%GTu>mj^S}i{; zB${_LT;JEmLv%s(uP!>H_dY=oJ)-v@h~7eU(G$YxL>Ik|K6)3TccPBo84L!4ck+AJ zI{(aCXWe_wK6^j=^PD?R=DAjVRtPMGC5OJ4=cBw|sex2$3AS0P09(-Zgxb4+%`ZY_ z(dGd5YEW-O2-?g|d^yhH(RTRNyAN-A-)gZ2j(+Ps<{WKsz-2cV7uFCT{tz0z5J2^$ z-)(aGQ^rdn>$hk0YMRTL$ftX14a-jujUOjrOieZ+_%o5p>OLZPUKp0IRv3+ndPoXv zvS!?~taj;te3r(ENDD^KwoG?Ll}v=*t}`Xv+`3hBpx@%Y6=)>`5YGag$ghxG=s~X- zu7$c40lfZv$QMvo{PyV)+(8!a|Gr94nd9k~#%XVLYz0dGbvRMr5vD}Y*Xf1c^5dDG zDD0tgR3z5sk?SsYn^VWSt8bls4dng+mv75|k@8&-?nIs*2yPcX&34e1J!*+Stm^P^ zb8}N(q#9a3^T&WP|9oMf9Y4F8_rcv7*;tbu#+yl%Q??rej!@)nmmiHk303?iM79R? z@GQ+GZ2z>Zymc1w`=$m`>%S2(XL-9~LT^A7|B!tyLco1Qvz0~Y-yXx*SH5^+?RxtH zOv)!sJTjKO-XN(47d0*L$jlrC2kwr=^S%yn&%z5GDkP zuBR8BFNdF#HAC;39@7JS6w-%p=cV+p)av+Jui_YJhAitPdYImj0C#cBVYqy=>mNeC zK6Qllp;&IT9Y(^fAS!;H(#Nf!DF&Ka`iYi`&h?TjaO^(|yJ7GEwRbKUH{h;D2pr`2HEbh4fPC#d+}y z*SY@~u%W5=3mvfi;*IFqjT6ez$f}@D&Nid>jM+^V4S(9e%U={(nrh^M*XWt#p$}p` zkD2FY(NKP8U^^txELUEVOSi~&Xzw>=O#nD$q*_Nx>B(|gAb_X?CIS}PGN+5w8PM&) zzd@t*=TF)A91X^THBz)|e`;&2PQES>u*_clZqN z6s~wDk9e1Pu1?W4j$C;|2WF`)t6ey)rPjC#%^Shh{DmQSM~+T3=LT)^cyL=dfg;Z zByNR6@7of8%;;&yOvN@b;$Y8%5F2w#_u+WH?%E(zMpH6U1mO!IdI3o7#;4GhmmaND z^gw=H>g`OB?R%ND-g|ABg-e^C0;RV*5Z|Dfc%);4`Hl4Z&FkABa(~*5BUf===4P1P z+bi3*SG(bRxBTw%4!jBuyz2q8@!ORduLJ@`YEz-NTvHL7G^Xzd7+liL8;nQgi4fqv z!arXJlBfwkr0bB5mZ=0a$NQO0St)O2?$w>pmSc!F9K;xYqx4=P7L|9S8s>+R-1n96yXX&V7X#5*Yl9 z_Y1WVzTIMbvSNDK7qK~_Xo0oE(+qt#pv-y|Rl*ir7Af6Dp;;zPeSsLmXXkzvUc^%? zA!-w#`;F)wZ~xMHTa2?rU&^MGzG9Sb^(Hu?gNUW+gY&CSqk6&1mXTNT&+pD89AXbV zaUCiRvNzOnYZGkAXJf_%AwYS0q1b5lKD_;a_pT5K4OYB!bNW(sEUmFu0^w9H_0=9;uWWb z42zgzW#ozeAR{;kM8O}la4wCVn`t{VSxz3)WYNzMbi&ul(N2f&GZhB;6@N5JfTFj> z_`%_mUG2RCRn?{r%0O4>juZ*Ui>%1!7^j1zviUBE42*@JxLpTS%3i+ zhm08$8oRZFam654Ct0$WZC_!`OkK*VbPz?uy$tlY2J|y^XmQuZ(s}50hWq<5@dlx| zGIU@SOow(M{ViTW$EyEB|IF3QeGW%z)%MxB{eY*p_)|FhNI$|DGck*oOSSWx3equ| zZ~9~ajP^rMyqhoH+L&>$;dPvSNZ((NdS=nCCRI+xo@9jL``&YTKFrkIW`n2#&GOuJ zY*SiNY1z(iUsmLLu53d5dNB!2@mX@MB7;M=XXJ10EcmmPD`vMV>Q7QcShq*5Cq@im zow!&>iX}k_27Gm}2p4t>B-4i|waS{u78=`-q#E?HGDykt!Z=rxau1BYZ~aYZuWaw< zSI)RZ1sjYpd`{dKd%vH9@Muabx%Ww-O-`XN7N(5Xr&gV4qNaW5V1Q8f)TMoubf^_&1Ub-H6?Kv^d3~_;JGNbyG#9Odm` zvn{dncQ_UgTaFIL57?l~TdQclTD<0WWc^$mXw?^Lzw6$^8l!$pg=UI!sOz~SjWHnjv^VYyb-_$l>6Y6UhI=)YLSztUq& zXn1|17orem#C;oyQ_W{^++Y^AZV~BM7J)+y}Q}ymOV{clliBFV<=Ufy;*O=E&`yP(Yl=S!l{KfQ!LQ*B5|3t-1S@TB=Tb zq_V&;9N*z2SnIp1h}ifLabFp3mx(#ZGV1wGyy|so9<;S#O-hKzTJFkc7~<8ETk0Z` z;>!6N*Z*E#;PYEvPJaK?Xbbc9H_<O5uF5K(_jeET~nkYBI&>Qj#x1F`E@rnP5^K9~lKL@lrBJwl|nnVJiJ z2QPQjUnh=VeekQ7S7S-K>a*~D*Q@aB4PpiZoSIkT*{xF)!{6u1xAttnBO$^v8^?D@ z5w_5avBaN%tK{F-;y1d7LA@?|YQI3^dg6$cel^(MG^6yA&=2a;VfHq43;p639tWk| zi{~#d;_w0VA` zNNUdaOQdg~6E=efd}zlmKVPedTo@03b82(EvfzJu5Ce+_(I%(QdAehT&rA&j635XZ zNAWZ(L)RTvUMmc{MI>+FL4rlrD(KC(S1OX>=1&nCs>swkqGeIB0NRjc5=0}pY}wT> zWZMUJT+Nuo;A7zjJcjfGCc^pa78;>d=>^{^U5CHoU0uTsCw6}=NK$>$u)G@ZW+i!R z3V0|_z|eLMO5by)ZyRd(WgX=2{Q-s7`mJ9o%`A?RmYOKmNk6PjFU$tV8^=Yl;|kiT z_V6-@E7hC@wtq^caS^80e9K=XryPoBBt!1u1K5Vme+Iua4LmU}MAHIo={;s#-&oP2 zTdVS$&W3quh$lcz!_ZPe z4Yr*LS< zz|Htr!6QlP#7QqKe}xI3_~jchiog9Y_=nD?W*h@r8GcUr`)fR}a6nm*q$vMb^rPyzLJi@fG6?VnBIHK`g}2-!byN(F@_&OR)d) zeLE%De!z+Vr6Zo{_5CLH78IjAOV+W*UYymq6$5P|HxgZ%|IXo;2NXs@U+I zhyy0@CMIq>O{tIf_cGFVp3U=_?4Xi?5$3VEu5IY~!gwH}sl~F#QM@t4pismtoHWSi zfJxW=>bn>x>~)@gI>}MTb86hZ=LcK*hdjUD-zR>vTEy%o8)&8uC$iI^?D@K`5rC^< zDEAGOdxUfNyi^-GDlp;bxEKFR0eJluyDg%vs1x zH{55HjekV$d_VeT(!(>=-&x&wrMY|e+OfJoP@glxhKBe2gNUKKYQM72XYI|Rm@J=j z4L4Z#Hg?McB{}`}wE>5a%t-Uv%kqQv6-Umnd(eKlC9dQwN#TE1dRWtA~=CHY-Hn z0R8^gn_kJOpBru=fO5vOu{e-Bx8}F52SSJ zJ=8SBJ(L&aBC!Y;9Y1rE<9HWfn)j}u`&COnP~q~xb{?Xx%-5E2cz=8@N|$ZX#?!mU z_PM9Ir~b8%TA+5wrb&>KK6S0RAIt9$EYc7CXxy+F|ELwgllLU})E>bE3B+7stj*}v zHT*VjGobj>{fdo$C@lhst6)VD=Dz5ER?(FcgF_leIn_0uoh{v(FoWSnw*hD$c%D`u#1Y=7Y4B2+X82?WQ0{Ox~!*K{0zHWY-){p zpW@a#UZ#`HijC#(1bF!?O|NbLjqd#T*HkttH;JE&)6@Tc$XV@t>rf5#!rR7V8H!cm z*Bu!!G31r)Ovm5&LP0{zVvQ#8Uk?>&g(Zf9OXbRFtaAyE+L{L||9fPHKiZ< z8OnEtp^L~x^?A#|2bYyw-ywffzr?U1#uVd>KjuP>cS|a68h1w~v`3(O$kTPy`qLip zVZ$zVxr^$%@GkAzcI=bt`%eh%_Ff*LV_V!9L5y@Bnx>7{6~p)w1>p~AmV}XWyvMUt zd*13D>cFPw4}8tp6vtiI_Ls0k+UlAm?Ccz~FB!Z{+na39w9+=Z5b_h`CNyTvpL#0Z z|L5;^$^)~&irRop=(N>5j|!$D6kL2@U-Xw7pg^>7`P_cTPoIRD<706(sf4Xl1ipIw zA`)Q!;?-al%APey<`C? ziOZ_NmPHYuh}~ZpC3LvsDWrvDZ<=Q`+ywut&F5p8=TGK|i|_w7r%rkqe!+BCD;T*t(S=-Qctn)s zJ|fhRU}SFO`iHwF`1(WB77cRs?D2%?>H2>C;iBYe_)FH)@%qCFA>K1t*$^T+1Pr4y z94$Z!jX`W}nFM?7nU5d(dQLZR`T!02=pYlae*5OR&)<)^Y7#K4?ho-LrQX-ywPGkQ^B+{ zBbm=Ea=LZ+oV;!4;sU07ZIwEmL9)I0G^E>(TB0&zo}kLRU_0)`bi#sF z=OEJM&BL1@JLW9a%=j-n3d)aNpn#(yjT3=&znpbLyN8 z2Jc0OZYWaiwps0+le7f*Oh%*Ra+zJf2Ao+sTBsH!?8}YnEMD+3?GBkR=B8~b39oWo zI4}Kp`;Gom^xq;JgzYZmO60KZ)TTAer~Fbj77w`vv-`BzF5C9n+|_XLoBus$kc;-MiUm zaA(I?H4`tL{tN0zNRbq)yC>Kny%UXniFaGNh;zF(lq%anY{N)a)HsiO>xXzHj*82S zu>7RU;r_3jS3qawbdRfFYgnj>O@x8R0(`^5BbLRh{gcvD%df%NPFis19|zcQL7rZl zh3PN*Jb7nTPA64P^Fh&fS+dHK?6ey%Y5i#S{Q;Tx%*&Ez#lrggBf7H?Q<;s$*Xt&K z=VScFsjpPIcrWKPUxHno;ukdaFEzB;0{Pr7*0wq?G&p(uv|XPEo_#b4wn^H}ETz=( z4Gp?ch26%E4d|YIRJn}xaD^N4%&4Q~r~Z2;gPrP^ncLW$-}Eb|3zazvm*|5yemmrl zpBn4v&-WQH2{Es2=dteAMm@B|+nyi{nXcf9*5P6sc0pX8=;qgIL3nY=d$>Dk^4fy^ zZ_0m(Y_uBJ0h-soBgfjV7#-$+A_--0KCY)fyVj;xjI(wP57asKPtoyP5i37)EN{w< zWCy!Dg>&?x%N%(jw0oac&IYuY?~Rce{W$l{AHd6hOONZ7X87|@9DM&}MQb)e_VWQ7 z=Zap8j(E`Ik321WctI7@+|sa}>`+1Xi-?Y@Ix&0C2Kk^vrw8~{?8J3#yk7bWW>bVqG z<&!p--DzO{T7YuzdB|4cy~ad!feamY+VDv?mo%TFSP^Cq~H`J z!AsM>1!rPCb*7IvH&~X$*v4xiA+qCp1jDsj@@HlLOOLxu{!xp!;x* zULSe;<6X41YuH0;VQkomsi$(hLSbf~Fw?ZIt=Z><>UQ2EF7 zyC7drN%IHJea-TvU#xZ5LvzlFJ74*g^6-sjlA^*Amw$>iM(1@y*!@z>efb?@Otqtj z83psUmr8~6-0Ahgf?gqILwzfUa#w{QdY8tpD|NrA`6yiV%a=SXV7}PGnZ8Qsm_tH7 zz&OXd!4eSF1W|B(*5TdYWey?*V8*9W@1?{373NJ`(|&cd@WN4b`DpZ;SFOBp#Bh84 zIl4*8lk)djzd98mfA~YqRR%3Ttc$T}ENpr0<`*exb~W_mEKp@wS%hiE*{!z)#8cAx zKR+I+)IC?fz{ai-YmiPj8A&BH^B-J$b}vaO@%+A!GwRZGN0_j)ps~l?#CR?*=5QjZ z!o}W*tt`Gb$jk<#Gn&Tnds&*Z02fg_yIgfMdDkkWuISLrdA>^J{e%Xdx|Kocg&R))K-cFF`;PW#7PvJlo9gd|dW7N#u3O9K4%ckH z-%BiyP?R6(|7Qt~F&5!VaGxn_>;0al<4~P*;+&UeZ&WHf64h}bw4X-GVE4x86%cH{ z1#^FQ?IlE8_LI=-~Jcrh+BuU_Mr_o@AvrjYWOC!HT z%r-|M6FmL~HW-he?9+ZnN6PAE;?$_iYSi@Rq&^_N1z-YoGPp+B)(nk8a&1HILmonI zg^pmt%|uh!H~P>$)+1prN1Er`tUF>{Qm;t&;DLI;2~wv7RBZ!v?)W^jPCH#>2i zn0L-iE-}8N6v@o*i=R(4xZ}v0*T?}6r$rr$7`!S)XG$eGt0=$*`33h$eY$Z|6;OVZ-a9zC^smu9`cHAYkjGQhJZ z?PJ|nV3F9#JqZ~09ro^^VUq2P=CHYgaR}IHTOHqwMbT?19kbiSlbjL&J3@avT8Z~D zZ66za*x*n8jNpNuX}HjBWeW?>d~Wup03|9PNA23L;{=**m8)GF=2bMvXWIYyIYbH~ zxF(}GR_>Vz#e?$MxlRW}xL^cjNw3c8b60%T{WIegTzV{%N)8uZKClrP9v{||vhbJn z&}7OzHnaryZ;yIHiD0+we-e2_ud}Q%A3Yp12j5j4eh!&Ac1>9^9>ojjXwtKcNygH9 zm&xstRAP=BbYUM6bmm5xQLH&fk;s+=G0^V@oqC6uM|x9hi4^0%U$z9kDHPr~y1Sly z>(7St9RB@@AtaiN{hHO(hhq!{?i&i}4hoRWtL?yM=d`!i?I^{2 zpR62Q!TtAFK$!}4R#VmrW-lIcYRzGqJ(~?XB6mDd$r%9pv0cIf^%nsu5_}1K zVKw@;sg=55cx?BCC2oLr(}zEdN5|$IbF9`?-3z>5Qp6mVY_ka@-Y+>^TFv13XVikM zV@l&_i+*$NMD2Sp>qASt+Jz=T4`gs|nzox}5}6&E5TM_RVqV~zAQSZ5jsd~Y9Ljyx z14jVkfwXG&zn&U+=3);wP@oNV^B%|8!G=$-q<7;5p1Am0Mh#k4bNO<48GEgZ0bn+0 z7Lm9*SP4%)&V81kO{mG&bqZ{5&AX+zhWdAyX38^o0rRJ+6fjOb5u)xj4n+Eu+0yWe3Fu&5<9_vP zebmB4`HBb$l#BlqhKX|isTJ#$9a{u?(OM58aUXs2enK|A4Q-*I)f0ItDrhby=9dJz zT)Pa*3HO0Ovvs1Z6v)%6S979GEY%~5sUnl0BmCvymjlrL6$Es z*Tr9`T+w<)&u{}H59V&DXd*QK(du1E#(Kjj4#~)el1Eu-j4(fJa`Q-EFd2a7% zEb6IOO&Y{7(p8X84^807YRTwJr1B7UVj{K>`YjHDNldLO`O^MGms8Kg5frGcLH0lA zv&15`Pa1x*FPaX`;vt*5GCe!jDWdZtsca1Su{z^R zsb);&WX2vHGi;9OlX|kzB_Re-Cb1Kr*Dz#4Z98|;Kv^~inX6E}Y4D`9e?%yDMPquP z*5oP7~^)uVxrlJkjvA*l(w>r8O~Y>)|3?ON@k zyQ!Y45e2Lbb48QogH{CHLmkHxCTLXP4b~VzM%@fff8`dXgI<)hGe^N23tU4wn_AS$ za%Tah#kYdrSZ{f!aQuJP0!v3GvcNGb!WLL_Su(KLZU&9&N}}o<8x5B8!_#G@Nru2< zj6gkmx#IYN^Slbd56;CZ6Ako0 zzNj_yJ7GXZdAYSV`+SBSBu>Ae1Xb6UwAX|Aljlpe=un*{Q{SE!{^rR67K;@|Q83@a zKLaD`LNMho%M=4?(l}vBd=`t%Hd<0j`wN(XjjHxlA(O%F5LN`+2ws3u_kywAHj>uv zPM#D9szJB#9hMvgTMh;21-c(`KZA}3=BP;`&*P%`B|`frnvp^iy)&=izy&~u)}FG=VkwYfhjf^K_ff|<6_nknuvpLAv#_yY7-G;I!Rd+=QiI{te(L4rw4*=0e0`>5SwFD z`y4wWxGt}}UTT;RUTF3s&X}!L8llTLo>)%pSQ35?L?y`Kc*yP4ry`>#rgzuIGdKax zo?+a+>=ksU312nIB43ZM)XH~3T3QFITF1DCKXBO7!@kWZSJr@I6jojb`!MI6++KH6 zTKqBz;fvubvI-W~(duK&@C;&ebw`OV1*BZ;7dKSPo;{Uk?vQgG3t1?0`d?M;@aeZx zl986dqS$C)v;Ka?rmoQ>WlH^SU19dN7b>P50~)?PIeMQ z$=7;KOS|tT`Cz)!(#sUEQ8Jr(U;hW_W@NKI6r|{4JPC?^{7AxX;&dD)!VF6(M`i7c zv}T+d*S2CX$oogl83AwX_c{kYT^?aa^HaCKF{sK|H+QF4Zoq@@&0j@l0$mt(QY+&XcRJmk1*cflQonI!eT!z^XWy=9QPz-+-&GoNY>@P>wvRPWz7O+ zHCzvmQ@LH#jee?$8d=-e+X;cR_9v3xC0@?1st$K{iu9VdEoV`}i6(PZ_Q()KFwaY# zRN}jpwq^DD{)Ja{$d4Ra8O*G$cG2W;_ej||%L^aJW#NezV}Z<-H3mU-{d3r@AfW@@ zJ(eYUFA%UvX|V+JeyhF3)%D)fKWBTec|c$0B6e~DaHmaG=a($FlWo`(_Gjx~uQyq) z3=5djX)b>8S5&HBMpb75RY{JXQiPM_fpL=Bj`h(VG1ZpN5kao5^_sIR1R7%@j{)D) z6)t3=iSJswQoK?vOmfRpLLFPg<&Lk9r&2aPOkB~skk>q^;m>iXzP zxy*dTM2TnGFQRG=gfsm<_Qb8yA_&vPh$;AMmnnvdTLLEl<{xIFl(MeE{EN^iitev{ z=KGGxhTb42w=Hzp3hhaOFFqZR7Ms0ts(g#aoc=ea`mwWJ`wij*m~E-1A*`}FiR}7m$3OQNN7pM? zc7yQ|682R;Ew_Oe+OR(v#E81D3`Q{;icbiEtQGu2_x}#}P4d>;Rs@$S^Cd_cq50zE z(zhHDw1LmztlTdiifP^F3-W{&J2CdYnOK6An}1;&InW7Ed?!WJjr@_k7G0bP4V)DP zl;_zO9k2jwu9t&Rp^d2+4xOm@)-kU;l40%Twdq*rvu_dt{8-#OI>n&2BCHLMVF79g z{G-o;)=*V+cLsa>DE<^wI}37k(_7|kDpe`53y@VafA@EYdHn@)4a#QJZFgYAu2EU0 zod0Ld$|wX(;DU#Lciz0{*P5K|SJ^;U?eUK`S_hm*RI=!mM~(JEKBE@Hd~9O)IY94= zoOvUmMnks#st}6SEy>6z;EqcA{h(`6R_t}00AuGo<^7|#NqYn?nwtZ0sC?|$!MuBZ zVK@JMZwh^GxKly6H|R5@;V{ZB{^ASI-|bXl6#6|jjiT$=tXOM^$U2KO_a~FXmsYuK zN;p+S1yGjku>W}4K_9xnd8)No(O@iV*+nT?bZhMx-XRL9%7qfn#pG=|klwXLdR+G5 zpd5?p_`)K4cKJ>g1+!_IWS!j8OQ(QVjH%E^v^$}riE2zx&SC`}Gu%H6a73?|?a-WK z=Ww2IooVeFE`uV@pOUrKK`epQGyGj57bpto6ihbBVGjPPHDg%i!s9azLI2kWZhZ+b z-#jw!q=j|tqRJShL$w&>%{oP8{FIqxw(HhZ`Ro3sMsGxPrl!XKa|KO61;TxuHxLEw`m))$oWddBtS1g{`SY83ynqu|e7^mPUB!<% z+vdNt=1_|Hd}SUmmSwlU*Gy!>2J#1>jKofk7yLrH%%^SJXi$vBps60+VtKiT;H)Sv zZkFwsK|;CQ!pg{Uz0IT?|5}kJV|vp#z8-P0f)zl$dcw~*?zufEZkMea81@M>$h3$3 zqy`=P<-Ieh<=&8SkJdSX$gJR@ zGQL{*TUl8pUD{tCDgR){h>p?4!FgfW6`{*!`MLg|s`r)M40{mgzl>Z6J9{vhsO>-J zq+?hE%3nZ~SEQ=tlsLTdsY2nPY0sGvJ5keYKPk6~>`EAI06xtBOXeL%u&Hd!Jc3m- z%`JHqv4ZD+;w)tn9ojmsqx$TjiIwni1tpq$-3(BMc%VJLuRfS}VBLfn=I`(SRd!BN z5dyK9r+#(ADEi!D*<_B8AwSovlw#uMb=0SzbB95kz!TTYrFDnj6Eo+Yl+v zYH>#kOD?O4rNv%NNnQzr>O+@fdgL*w$p2D3q@z^rO)>w7zJG)(R%f-#5%sN+#q!pJ z%n6aTBmJG|zUL%U?(UxVEQ0jfz2Lab1aR!{+U7xV5npA_{%1@?y{e{!${&ww*AN>~ z->l7HzG)JYD|}FBQ^)_YV^jDY;Ey6|3d&OX{SZ|D`94EsBSrei@E<4ikvJ9x49{GZ z%pR&zqMXj5XnD8hwmV*-MDE_QiG9wOACsu~==(XbuCx&zVe?haOw* zOnay%0tT#zM-DSz6W=96$O3Oh8}$EK9cCIw6C=fi4{kfMWYaXi;ducx9xSMP+-D=I1{dKj3Y*;DhEnm z>>7jP>}{*&^l1Z`;W2FVdR{-c&h>;|cgf_e9LIgr-(MgPH2W00m@7E3HRYUhjWR>L z1|@e!_uTr#N1{jOvzr+70NC;iS*bZz-TG94_ zx5yea{R`{FAohbiTq7l;-QYU($&2>6^K(Nktd+4dnJN3oph8%%C&(8GiLCX7Y}g z4*BYpJui`Dt9SvN-iTPJ1;|4gHmKX90uKTOwLkxNTk6}Q zYyeY?%>$8rR=p=GqzgbfcK)|S4OY_)>wh+R#y_5Wd}5VAP(ah>3f0Y;QyQrHoETp5 z+{upM1e|y*3^7o+Hx}E29yvriCIrzf+E$GJpN@kshNH)4#h!PKvAL67!a$Q*xol|Z z)QJljY|y>DOw-i@F{AE1-$IK5ni4}x27}}KPtG-1?AF6Ie+0gGAM@0pz&MGAV^}h3 zn$dq)OdiN1`9k4I@l6k3J!XgJz*zT!$Z7nP0eocW)-r>a#p99?086Q&HGs`Mmr?!6 zb{AW5Hi;540vCJyYavZ?pARDvN~__8`p@)i*(%1L^< za5Zd4JIkGiH$^Q7R8=}_lQE#P;05Iyc@6t>Gw&DVY}HjR5^WTSGbjumz{IYfp3CyT1Db-xDE^XN#d4Ewa z4uI(y8T}ldsO_~JuNp~ay&%#s#$HDcFz?wDfm>%PbWxnSp%|s%mIceU)9#H^O8jLs{`&RIk>hJeEi@W{EVi6uR?w#Oz$#jI2}YjJsq% zNK*!p7if7qb(hrk&@JS7;XZKg4YuCC{)^{-MR15kFLMa;+kN)v1bt9E6KBJBkU+aKa4A*nA9^IUuRfND7en=tt|1f2{1eJT>9|H+upag^kGh z{G(Y zu9dLs$MZMpr<i=X+*b3gUpsW)N)xWCq4cMT8(aYj3vKo$OH484oOMyyy@9y=hTOSJ%&pv zExsoDZ1dnqm<{7RtZhV#8gaQUBznxT*(E7p|NQc{f5^MH;1J0_L_Qbx=S`4~cCk@Z*y}gWc@- zdjG*kDG%)}J52AyW{Gil-oc|YnE+vQ1F=B^&P-m!?(taJM_tFEpu1BNi{OY*@yY0h z_G6=X6|v4avnc?sQYDp4PcM9JVPs)@6n8jKOpI`dq518m(dg}giHgS1oOxyUL`+kj z6<@h$^2E+~!5_RL-zs|ySw6{myr6lHD35HM;jE57g1wI#szyERW0LNITX81V>>5V- z7HQZw$(M6=yOo{|L@AjwAFC$MWL%7Tv?PrkeJ}O_vjK&!n2%778&%+e4?7zx=ViOv zkL~JarF~DsN%pG}>DR%(wCX2y0h(EY^1)6X_gBGs5H>o2exubmdGF3*azw*d;OR!3 zPRrJR0=auqdKr#%Mj^QrFp(orL(;ejT)88ufIScZyF?G#svRepGl$w#kD4FRfPd;1nO3a|vRYG_tO`)ypDAD2lZd;(hUZX`Inybm{)? z$M{+;I!FSRq?@5wN=5Nnxy@qrb3kM}E^< z^cm-a)E&isMV80@=bf%8RSVbr2@`m-DDeU@q&J81_Q*SN*#hC(%7nd$&EJ)N;$&N{l$s zkniGQdeJy4|7><~3L@7PIY*;Qknc%n6if|Ja~#8`XNGT4-*a7ig(GS1{Cl>rr}UvS zn<|xy4Ep_A$Lx=q_&v8$`cTw%%<3M$A(KlQbn1m{tGZEC!#X}J6`&uSZ>IGZBwtmt zx6?yszc&PT)!)B2v#RV=6hkfAROV&00B><~)u=&!;)BuvUf}BX@BB`oa2ui5PYJ%p zR|gs7cXjFR07Mk_jrQ44z)y}-%MVzc-Yur{lYCsyNZAKO&Ks=5JANp-bSd#YaBDM# zbO+C7ur^18{G*(w$+}GRe=ax$6k74!BwtId<5Km`rWrmaf0rE4Y#Y&ew;A_0V`(ym ziy=jF3abUdw19_17Gvgl?ogni7-w+n7>P1uzJw2Gk0H00W6nDBMAiI`Se@oOk(kJS z+|m#IO%a9xu`U=vt{#pi-FynRNqZua4D84MjH;@^xa0K1-FB*qooB9dv_YoQJ|sf) zzd5$^0n>_^Z}|fE5%I)#JeBP|gZ^ZyzMKIOwPZElJ^i9G2>sk_^HgUuitP6am2X{K^lKDm1^#fwvC1 zoizsOV*ZsrN$OlBC~+77>YJ1VPqT{T3jCLEu{#M2nRspP3w*&-4Rgc{G7BFdM=EF` zRSb6{cuuvd$q{uNF+^}9@RqI7O^u#+Ycu(s#tF+|sBCQJzU0h*cy05=1b4JbnNsTa zel0(fYgfjz{=PM-blLbA5o9{0#l>3<7m)>fe*dy8J0Y#KKjZPM2O`K*)6qc+oC z5cV+5HtxYyEo*}rggT<~6ItC47XcK34Zq_$(5~GLcMjhx66sk@+f=JltTxg{R{yK( zrJZO8!ty4mBp1Dp#R)H!`9x7xR^&RVJf=bm9xi)Mp#T?MK*{^AARkoi-Hd9+prd>c zg)?SnV(P-s-m8;O;vQ4CGKmgWB^r%uerPEwLD2mjpK%1cUk1>X9U@CK&|pvMu#wf4kc3}7m& z9zZAqlx_vY`fK8_~SUa@V~^ZtY{pS2#5utG3@Y6Z1HImLHBTn!gdXJ)osm|^||{vDqb4Py6qLj;TLGD;)0Jh82f3=W)q z*dzIgP(C4g5a(fPuY8y7W|1B5%&MNONm=XPH}L?Yo&~+Tmo4MEd-rcVNQD6K<2PT9l*IEf?lLrdx6X_{|bQPF%f5B>TV`(!Z9kId=(hWoR=Iwl_|8Ujw^To zh~@GxG9+5m0g2)|)V))z;z%qQrOfonz5(lH;X=X4jIkK|h4}&wQanuSr_!!=W|(e? zN7tLPrpn2)vD0_idhnQ>5{L?Q9>vW?eQ1zyt8huS4pa;NclgxQDI(Ck1|)o1AoNzU z?WNu&ZYKF%JM7w%Isup(y@$J8Fvg=YiSY4M8aimRHZ^8f4M{)Gr|?3G`!V7&E7 zz6Th`t~sD7OU;jhXrv_|d7WgUVl448lSZiJw2U0-{QY5}XcKVR@B2H6Fwi4v{n;b6 z?aA1Gx(MCh1!|Yyh4(gvu$bXd6mvr|MxI2(y}>0yxo3UHUGt?Uw^zPwZ+Po8`zS9RDOjD^ViVJxDHhiE^ z9rn>3%*V~T#2C-P*vUQCi`>7m4ntjATJ7#|IS~1yP28gpQag9`=g{sOF2M1i6=c-t ziTsXiH%wyO{KO=m5C6{ioHiXOQr0WHN#^d!gF;|*SfLX(Lf$sj|I$Hp6A zvfbwH;1w2G(x;CWTC5`2>o~~T`Krqz-lG)B?1{oJ317FI-C#W3dzb;S$mf@kq2Tt` zqSlxOa)b?9@T@erVZzQbC$I|eckqQ0Y@ujhqN_Eq-b?x!JDcT?DZ4Bs*pab8Ecsxe z%y{a``T7m8^IlGI4hj9i=>MY$>~hCVl#sG zB(D5K6||$ngT9!&Sb#G3C*C%4z!bE{fcl{UNGl4%9L;<)&+uOd2YXlGyBp`P`=-N^^%f`k0yBGAT0{C&$&5bt`C^ii!%lNJdpj&)t?X%=1+IUdM2^`MU?OLwu z?GkH4CBj0noq}CvRnr{Vs^bt|fYIK_A^*bc731h>w20n1H+2XYzQcxp2X9TSu4hXD zwumkc)=0PPRjyxZW+Q*hq2*622({~W*NCnRfHhuW9f%wfTHQ+A-45N(Iiwu-MN#~+BGX6jNlq>2 z9Oo>@SxAm^Y!v3yHs`Tno9(mj{QiQ^AZN{d73Y?VBv2if+elgqFtTX) z1Fs{exR0xDFy?QU&ic!_<8rj6cw4PPfGKkzw|n_q zx(bWmdAeN(&!urpp|oPBgxz<@@$oFx=zis? z1eBl|)S6UIfB+>*_-s0?jBwEmN-JyJpndsPaPdtZzCdlOhti_~rAw(%?l7ee1J&*s zTi^|6dDJ=9syxq!=@geuNp%a__~I3d+6?VKV(#C4(_r(o)uSFQjkWq;UNdW|PVT3L z+5@s@#(#-&<)QTaq_A-)M}X#*_+#Md8cVqEKvM+_EMTAvn_ro%PXtj^W=XqP zrn(pX<48FDTrN(Nat7=7`C)n#o!k>JDCY!aQM*a|LTIN1w~tAUqwYzR|DSZtcuq!G zgPlPlCKpj+=O&h-6$Fuk+i%9+zU;F8R4VTmOzcDJY~vAl><733WoxZ;-8QG5aMhd0 zv8G8qF1^egdq_{$+iQMpw)ICYu5H8N(YFhCWQY;!Q_4<{>46>8OD`bh3;T~l6}!5_ z^FZLNT1)u(xX=$dlIre?HEA#uJPMLt(NQeS72HDt(N{s|%oS3-C0L6_GN0EJi_D1_ za#7co@{En#eB!96S2t9kzUZy-aq&Sz5C18`O@khu`pc*PX0Scd9h@xcxD#!pzt%6$ zDmZ~A{)>)7L)arZQsr~bVvJP}dq`oNs%u6R*x^yWmIhNK8YWj)|9Q*e5N*><+bFF| zjMwmqypS2T{ZD<`Goq9Y`4~^8$Yw8lFMMIX*Ohq~Mehe`&=)g9@1BH24kZaaHJ*@6 z$sTwpgxY*E_6gA^$|FTo+>%vz#wnNM{-lf^L7(;B4f&|qpFj6pa1zd*Gp%{(s}+jr z%?8V#DEFpUdIb_kseD~rniUr0vlczR0;!bVwY`5rgCjySTkS8n_0@h+HyTcADjlZF z|BaO;Zqr7sm*}npvdN5bsPZkvnHQ*{bTOXXzlVcvr6K~!jC(cGe!22+44B@YRH+;jaToREjq!%B$&?vB% z+0iSSdCyleCKjGl8fC=m+h)SX3 zh_a*-fmo0@jBvMrZ)b)kDR%nSW~GL%321;csdFB%J+Az*Ic?#cj6T!X0`He^XSO8| zjvY%qcO#1ZPtyodg0@5lt7fWx$B>@A+gg6l|_| z+JGa%K|c8su~a~jwO3;OI?H?gV*qT{x>c3-jHxw@b2ld?8vmYm?u9`*d3BF9X9Hj_ z6sfMudUumctpS(>Mqv=jP{RoPV(k34=A*pqv|ibZ3Qot9+N5_q1rj=oj0N7Hez^qC zKi6O}j-Xwv(0wMD2X@K_gRZiXVOdU|Nbut-AAfW3m-RdTVZ~lCkr`FRdIneF)4%&1 ze#Zy3HtmRI_LV{V(#D?-L-=# z&PC_<#24m{GeSdNx6Ra8qW^Z>8PJzcgolGNZp2Kdkkwss;b)lrlgoX78~wgknCJFa z=T1+>+~!PBpEx(;`H&D%%ZA*}=>>y;S5svQ0_pgx z&oB!85O7U7o`2&sx+EDU$Vxay*+K>30uCM&Y%t z3>o(I@EN7UIo#G*x3`00+`5< z*j8C5jFuZxtW|J-wO0BNN?Y}No~@Zg)5)I-ME)$Nu2E#6bdBVum3K|M7OrWc!NmLx zqkkCkC~;Ou<1a^yLeR*nclCtYu2J(|42TtY47)O^U8?MEmZdoSVCQOCmnhFPbEdTe zUPzpx$?uzFT?$=u%>_5RrCB;1Upp(!*)I$`KD&N47b4EV1urKfhp1M_GN)|P!C3D( z+|jUYQf22oitC)clbngYeUE_4n#uH5*IJhBw#YVXYkr;M;3eE{*y1G#yZ{)Da|SEE zYT*l4qVSs4=xh~pvj_UNX8Suos)3M$_4An^1rS;xgD(t*ILJNya>@SGXay1#RJue_*q%d6adr^7v4j zZdR9G@^`y!=~{tod7yThTMKf00CaC{VRo;bpws-;+G0k*?Nz9-OAq}q#uNKmO04i& zlWQqQmZvIL9y%6GaTniiKV?b|>$qEEOXFn~K0RkqvvzJL;9IQen3t z407-R!o>n2&Q#iJwS=qgN89Ke*fADLPwRi5Fp6A2ewA~Le}Fjq0(*uof(br(T*`R; zW@@c9{(XZbmNcB+@Z+08pF(7VqSL>_V zkTtt_{RI7HA{NBlZg44)-6fL$O~wD+q);ly3Vgl)A-o=WjT`=RD&%bTfTu8eJuv9J ztl>m=J}KWWcx9eqU@u_Cvi{aNxPyy;y_xkAu+>OUM2XvhIeaY^FEZzexnvqRxNID$riFnbr+gz>n z0xc9lG|^+1Ix_&^7TT?>J|w2=bCN)-~e<$ey&6$h_5pVmQ^ z4-@q{%K5Vp&*4;WJ&5#0839~mxxKbyV(C~ZYgZ*4^3AZoQuC*r?5&RLKPTV94pia9 zcRLXqht4a1Y^^>;+_$FhK^seCsw7lh!`LS#kfU>DZW_#xdX2hJ+?yRSYA_+=$rJO} z(kv~_In2zD>f5F#CWt3`0{b!XW90h>ukxG|u0+R(rZ z{!K}zJmO^e90cKuCz)REwAo7z`~2l(1BeUD(eC+FjBjSwI}!C0U{RqXo#GJjZs62fv_FD4Ar|nosS{S8i;W#j9DS|S7mO#Z z=laibtWtstJ{tF+N-Ee@1W}-&Lnqp{tk^ZUMFZp0;g6D~OI?0xv>PX*@55Z_Q>}P) zCdZmCl{Mqe{27gPDu`LVA3Uo2_K_f=NiWlx|6YHo`p?iIz^3=+HSOcR2N6Iy#(6wo zM5Jh7N{f?;EP)y3&s2TIehb<%4SeM;z9gb4NV$p1zTC<=NG`s1s!Q@@d52DanTaL; z`!2EGm{^_y<$C-SLj^uls(1}fGzuPaoJdthw)hL-Kdz^Ye$T40WnHFa^S}-}cLeqE zbEBs3^6jxD{cl{D>e07PA`&|hhtLvs%+%JGW}taUi2tCZP6eHm^!z$_Wy+WoR>^iO zu`jDRf_|HUyv0*uIeth?^532oRE^7=vpP~|e4rWs)mc zo&GWC%qadFln$F65ZRzHR^y|fL9d@rYgPuF>BXVm>Ejhpq8XIVIKqFdzEuZ9{K;C~ zN9_r13ZK3G*KEG-`ll6#ik z>~bbEY$oE~J7dmi+TH_a;+fiJH;ToQPVHTY%x*bC2<2jl9gq3_iuIhO7F2CiO%TvS zHz3YE%IFkPCd%3`%z=ufS@|P@c0bYG?J>(iysf*ePyv0_e1a6jjmf+lwHkY)Wl}mGKq{uwWDQ3Eh)*79|qb1IMw4{%FQ zqcjI5`Ks=xGnQ06sukk!@{PzAxw^5#Tss*Oc!Q9BWQ*+ewRP4Y3R^S`j>gGTx_Q=< z2h$CWxF%m*q35x*>t?q5&K2aVoQcmM7VAbo>|Qi!|KsFpJf!)E1l*pfst?3!sa4W#g?1xv(uwTNQ_hc3)w< zcF06*)H@5i!(SoD#l^>u4kEf@<6cSQJc8^<%stKb*f#YWUnuE07V#q|Xw^^hmgK!J z_+|rL&6X)ENm|hle(sId8Vo?9s z+l$`Y`o0?UkoqES|qi<&in8 z3*3!8{vMyzL*@bLSSG>-O<`pL**d^Fkq_Yb3?fTB2|bQw`v6o$fF%XyZL#vvvt&jK zf3Fz4DaGApv4MUf7DzTL>VeaX!N5L$HvxmC#KFsSw?@FgbN<#Cg1;lh-_il|b`|+7 z*3u%s6U}1p@!7w~d}a$eVs3vE%zlwX Yh=AT}+{Z8S*?0iGW=!6_#yo!Le^d>KQvd(} diff --git a/src/TutorialCode/Tutorial5/mymodel b/src/TutorialCode/Tutorial5/mymodel new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial5/mymodel @@ -0,0 +1,147 @@ +/* + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Virtual Leaf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Virtual Leaf. If not, see . + * + * Copyright 2010 Roeland Merks. + * + */ + +#include +#include +#include +#include "simplugin.h" + +#include "parameter.h" + +#include "wallbase.h" +#include "cellbase.h" +#include "mymodel.h" +#include "flux_function.h" + +static const std::string _module_id("$Id$"); + +QString MyModel::ModelID(void) { + // specify the name of your model here + return QString( "new auxin transport 2" ); +} + +// return the number of chemicals your model uses +int MyModel::NChem(void) { return 2; } + +// To be executed after cell division +void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { + + // After divisions, parent and daughter cells get a standard stock of PINs. + daughter1->SetChemical(1, par->initval[1]); + daughter2->SetChemical(1, par->initval[1]); + + +} + +void MyModel::SetCellColor(CellBase *c, QColor *color) { + // add cell coloring rules here + // Red: PIN1 + // Green: Auxin + color->setRgb(c->Chemical(1)/(1+c->Chemical(1)) * 255.,(c->Chemical(0)/(1+c->Chemical(0)) * 255.), 0); + +} + +void MyModel::CellHouseKeeping(CellBase *c) { + // add cell behavioral rules here + + c->EnlargeTargetArea(c->Chemical(0)/(1.+c->Chemical(0))*par->cell_expansion_rate); + + if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) { + c->Divide(); + } +} + +void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { + // add biochemical transport rules here + double phi = w->Length() * par->D[0] * ( w->C2()->Chemical(0) - w->C1()->Chemical(0) ); + dchem_c1[0]+=phi; + dchem_c2[0]-=phi; + + // Active fluxes (PIN1 mediated transport) + + // (Transporters measured in moles, here) + // efflux from cell 1 to cell 2 + double trans12 = ( par->transport * w->Transporters1(1) * w->C1()->Chemical(0) / (par->ka + w->C1()->Chemical(0)) ); + + // efflux from cell 2 to cell 1 + double trans21 = ( par->transport * w->Transporters2(1) * w->C2()->Chemical(0) / (par->ka + w->C2()->Chemical(0)) ); + + dchem_c1[0] += trans21 - trans12; + dchem_c2[0] += trans12 - trans21; + + // Influx at leaf "AuxinSource" (as specified in initial condition) + if (w->AuxinSource()) { + double aux_flux = par->leaf_tip_source * w->Length(); + dchem_c1[0] += aux_flux; + dchem_c2[0] += aux_flux; + } +} + +double MyModel::PINflux(CellBase *this_cell, CellBase *adjacent_cell, Wall *w) { + // PIN1 localization at wall + // Note: chemical 0 is Auxin (intracellular storage only) + // PIN1 is Chemical 1 (both in walls and intracellular storage) + //! \f$ \frac{d Pij/dt}{dt} = k_1 A_j \frac{P_i}{L_ij} - k_2 P_{ij} \f$ + // Note that Pij is measured in term of concentration (mol/L) + // Pi in terms of quantity (mol) + + // Equations as in Merks et al., Trends in Plant Science 2007 + + // calculate PIN translocation rate from cell to membrane + double adj_auxin = adjacent_cell->Chemical(0); + double receptor_level = adj_auxin * par->r / (par->kr + adj_auxin); + double pin_atwall; // pick the correct side of the Wall + + if (w->C1() == this_cell) pin_atwall = w->Transporters1(1); + else pin_atwall=w->Transporters2(1); + + // note: pin_flux is net flux from endosome to wall + double pin_flux = par->k1 * this_cell->Chemical(1) * receptor_level / ( par->km + this_cell->Chemical(1) ) - par->k2 * pin_atwall; + return pin_flux; + + +} + + +void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) { + // add biochemical networks for reactions occuring at walls here + dw1[0] = 0.; dw2[0] = 0.; // chemical 0 unused in walls + dw1[1] = PINflux(w->C1(),w->C2(),w); + dw2[1] = PINflux(w->C2(),w->C1(),w); + //static ofstream pf("pin_flux.dat"); + //pf << dw1[1] << " " << dw2[1] << " " << w->C1()->Chemical(1) << " " << w->C2()->Chemical(1) << endl; + +} + +void MyModel::CellDynamics(CellBase *c, double *dchem) { + // add biochemical networks for intracellular reactions here + + // sum all incoming fluxes of PINs + dchem[1] = - SumFluxFromWalls( c, MyModel::PINflux ); + + // auxin degradation + dchem[0] = - par->aux_breakdown * c->Chemical(0); + + +} + + +Q_EXPORT_PLUGIN2(mymodel, MyModel) diff --git a/src/TutorialCode/Tutorial5/mymodel.cpp b/src/TutorialCode/Tutorial5/mymodel.cpp --- a/src/TutorialCode/Tutorial5/mymodel.cpp +++ b/src/TutorialCode/Tutorial5/mymodel.cpp @@ -19,80 +19,44 @@ * */ -#include -#include - -#include "simplugin.h" +#include "vleafmodel.h" -#include "parameter.h" - -#include "wallbase.h" -#include "cellbase.h" -#include "mymodel.h" - + static const std::string _module_id("$Id$"); QString MyModel::ModelID(void) { // specify the name of your model here - return QString( "Growth hormones" ); + return QString( "auxin flux and growth" ); } // return the number of chemicals your model uses -int MyModel::NChem(void) { return 1; } +int MyModel::NChem(void) { return 2; } // To be executed after cell division void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { - // rules to be executed after cell division go here - // (e.g., cell differentiation rules) - - // set one cell to source after first division - if (CellBase::NCells()==2) { - daughter1->SetCellType(1); - daughter2->SetCellType(0); - } + + // After divisions, parent and daughter cells get a standard stock of PINs. + daughter1->SetChemical(1, par->initval[1]); + daughter2->SetChemical(1, par->initval[1]); - // if a source cells has divided, one of the daughters becomes the new source - if (daughter1->CellType()==1) { - - // if both cells are at the tissue perimeter, choose at random - if (daughter1->AtBoundaryP() && daughter2->AtBoundaryP()) { - - if (qrand()%2){ - daughter1->SetCellType(1); - daughter2->SetCellType(0); - } else { - daughter1->SetCellType(0); - daughter2->SetCellType(1); - } - } else { - // otherwise choose the one that is still at the perimeter - if (daughter1->AtBoundaryP()) { - daughter1->SetCellType(1); - daughter2->SetCellType(0); - } else { - daughter1->SetCellType(0); - daughter2->SetCellType(1); - } - } - } + daughter1->SetTransporters(1, 0.); + daughter2->SetTransporters(1, 0.); + } void MyModel::SetCellColor(CellBase *c, QColor *color) { // add cell coloring rules here + // Red: PIN1 + // Green: Auxin + color->setRgb(c->Chemical(1)/(1+c->Chemical(1)) * 255.,(c->Chemical(0)/(1+c->Chemical(0)) * 255.), 0); - // white: high concentration of growth hormone, black low concentration - double val = c->Chemical(0)/(1.+c->Chemical(0)); - color->setRgbF(val, val, val); } void MyModel::CellHouseKeeping(CellBase *c) { // add cell behavioral rules here - if (CellBase::NCells()==1) - // first cell expands unconditionally - c->EnlargeTargetArea(par->cell_expansion_rate); - else - c->EnlargeTargetArea(c->Chemical(0)*par->cell_expansion_rate); + + c->EnlargeTargetArea(c->Chemical(0)/(1.+c->Chemical(0))*par->cell_expansion_rate); if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) { c->Divide(); @@ -104,16 +68,71 @@ void MyModel::CelltoCellTransport(Wall * double phi = w->Length() * par->D[0] * ( w->C2()->Chemical(0) - w->C1()->Chemical(0) ); dchem_c1[0]+=phi; dchem_c2[0]-=phi; + + // Active fluxes (PIN1 mediated transport) + + // (Transporters measured in moles, here) + // efflux from cell 1 to cell 2 + double trans12 = ( par->transport * w->Transporters1(1) * w->C1()->Chemical(0) / (par->ka + w->C1()->Chemical(0)) ); + + // efflux from cell 2 to cell 1 + double trans21 = ( par->transport * w->Transporters2(1) * w->C2()->Chemical(0) / (par->ka + w->C2()->Chemical(0)) ); + + dchem_c1[0] += trans21 - trans12; + dchem_c2[0] += trans12 - trans21; + + // Influx at leaf "AuxinSource" (as specified in initial condition) + if (w->AuxinSource()) { + double aux_flux = par->leaf_tip_source * w->Length(); + dchem_c1[0] += aux_flux; + dchem_c2[0] += aux_flux; + } } +double MyModel::PINflux(CellBase *this_cell, CellBase *adjacent_cell, Wall *w) { + // PIN1 localization at wall + // Note: chemical 0 is Auxin (intracellular storage only) + // PIN1 is Chemical 1 (both in walls and intracellular storage) + //! \f$ \frac{d Pij/dt}{dt} = k_1 A_j \frac{P_i}{L_ij} - k_2 P_{ij} \f$ + // Note that Pij is measured in term of concentration (mol/L) + // Pi in terms of quantity (mol) + + // Equations as in Merks et al., Trends in Plant Science 2007 + + // calculate PIN translocation rate from cell to membrane + double adj_auxin = adjacent_cell->Chemical(0); + double receptor_level = adj_auxin * par->r / (par->kr + adj_auxin); + double pin_atwall; // pick the correct side of the Wall + + if (w->C1() == this_cell) pin_atwall = w->Transporters1(1); + else pin_atwall=w->Transporters2(1); + + // note: pin_flux is net flux from endosome to wall + double pin_flux = par->k1 * this_cell->Chemical(1) * receptor_level / ( par->km + this_cell->Chemical(1) ) - par->k2 * pin_atwall; + return pin_flux; + + +} + + void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) { // add biochemical networks for reactions occuring at walls here + dw1[0] = 0.; dw2[0] = 0.; // chemical 0 unused in walls + dw1[1] = PINflux(w->C1(),w->C2(),w); + dw2[1] = PINflux(w->C2(),w->C1(),w); + } + void MyModel::CellDynamics(CellBase *c, double *dchem) { - // add biochemical networks for intracellular reactions here - if (c->CellType()==1) { - dchem[0] = par->leaf_tip_source; - } + // add biochemical networks for intracellular reactions here + + // sum all incoming fluxes of PINs + dchem[1] = - SumFluxFromWalls( c, MyModel::PINflux ); + + // auxin degradation + dchem[0] = - par->aux_breakdown * c->Chemical(0); + + } diff --git a/src/TutorialCode/Tutorial5/mymodel.h b/src/TutorialCode/Tutorial5/mymodel.h --- a/src/TutorialCode/Tutorial5/mymodel.h +++ b/src/TutorialCode/Tutorial5/mymodel.h @@ -53,6 +53,8 @@ public: virtual void SetCellColor(CellBase *c, QColor *color); // return number of chemicals virtual int NChem(void); + + virtual double PINflux(CellBase *this_cell, CellBase *adjacent_cell, Wall *w); }; diff --git a/src/TutorialCode/Tutorial5/tutorial5_init.xml b/src/TutorialCode/Tutorial5/tutorial5_init.xml new file mode 100644 index 0000000000000000000000000000000000000000..593dc26168e75475ce9e81ef66669fc9cadd085b GIT binary patch literal 6905 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 zIifJQo6=NChem()) { + stringstream error; + error << "SetChemical: value ch = " << ch << " is out of range\n"; + throw error.str().c_str(); + } + for (list::iterator w=walls.begin(); + w!=walls.end(); + w++) { + (*w)->setTransporter(this, ch, conc); + } +} + ostream &CellBase::print(ostream &os) const { diff --git a/src/cellbase.h b/src/cellbase.h --- a/src/cellbase.h +++ b/src/cellbase.h @@ -118,7 +118,8 @@ class CellBase : public QObject, public source_chem = chem; source_conc = conc; } - + // set chem 1 to conc in all membranes of this cell + void SetTransporters(int chem, double conc); void UnfixNodes(void); void FixNodes(void); void UnsetSource(void) { diff --git a/src/flux_function.h b/src/flux_function.h new file mode 100644 --- /dev/null +++ b/src/flux_function.h @@ -0,0 +1,22 @@ +/* + * flux_function.h + * VirtualLeaf + * + * Created by Roeland Merks on 07-06-10. + * Copyright 2010 __MyCompanyName__. All rights reserved. + * + */ + +// This header file defines a macro "SumFluxFromWalls" that attempts to hide this +// horrendously confusing member function wrapper construct from VirtualLeaf's end users + +// required format of flux_function is: +// double [model class name]::[function name](CellBase *this_cell, CellBase *adjacent_cell, Wall *w) +// e.g.: +// double MyModel::PINflux(CellBase *this_cell, CellBase *adjacent_cell, Wall *w) + +#include "far_mem_5.h" + +#define SumFluxFromWalls( _vleafcellp_, _flux_function_ ) \ +(( _vleafcellp_->ReduceCellAndWalls( far_3_arg_mem_fun( *this, &_flux_function_ ) ) )) + diff --git a/src/vleafmodel.h b/src/vleafmodel.h new file mode 100644 --- /dev/null +++ b/src/vleafmodel.h @@ -0,0 +1,20 @@ +/* + * vleafmodel.h + * mymodel + * + * Created by Roeland Merks on 08-06-10. + * Copyright 2010 __MyCompanyName__. All rights reserved. + * + */ + +#include +#include +#include +#include "simplugin.h" + +#include "parameter.h" + +#include "wallbase.h" +#include "cellbase.h" +#include "mymodel.h" +#include "flux_function.h"